线性表设计与实现专题讲座Word文档格式.docx
《线性表设计与实现专题讲座Word文档格式.docx》由会员分享,可在线阅读,更多相关《线性表设计与实现专题讲座Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
A.班级中同学的友谊关系
B.公司中的上下级关系
C.冬天图书馆排队占座关系
D.花名册上名字之间的关系
线性表的操作
创建线性表
销毁线性表
清空线性表
将元素插入线性表
将元素从线性表中删除
获取线性表中某个位置的元素
获取线性表的长度
线性表在程序中表现为一种特殊的数据类型
线性表的操作在程序中的表现为一组函数
C语言描述=====》线性表的设计与实现
人生财富库积累
#ifndef_WBM_LIST_H_
#define_WBM_LIST_H_
typedefvoidList;
typedefvoidListNode;
//创建并且返回一个空的线性表
List*LinkList_Create();
//销毁一个线性表list
voidList_Destroy(List*list);
//将一个线性表list中的所有元素清空,线性表回到创建时的初始状态
voidList_Clear(List*list);
//返回一个线性表list中的所有元素个数
intList_Length(List*list);
//向一个线性表list的pos位置处插入新元素node
intList_Insert(List*list,ListNode*node,intpos);
//获取一个线性表list的pos位置处的元素
ListNode*List_Get(List*list,intpos);
//删除一个线性表list的pos位置处的元素返回值为被删除的元素,NULL表示删除失败
ListNode*List_Delete(List*list,intpos);
#endif
线性表的顺序存储结构
1、基本概念
2、设计与实现
插入元素算法
判断线性表是否合法
判断插入位置是否合法
把最后一个元素到插入位置的元素后移一个位置
将新元素插入
线性表长度加1
获取元素操作
判断位置是否合法
直接通过数组下标的方式获取元素
删除元素算法
判断删除位置是否合法
将元素取出
将删除位置后的元素分别向前移动一个位置
线性表长度减1
3、优点和缺点
优点:
无需为线性表中的逻辑关系增加额外的空间
可以快速的获取表中合法位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化较大时难以确定存储空间的容量
线性表的链式存储
链式存储定义
为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
表头结点
链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息
数据结点
链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息
尾结点
链表中的最后一个数据结点,其下一元素指针为空,表示无后继。
在C语言中可以用结构体来定义链表中的指针域
链表中的表头结点也可以用结构体实现
带头结点、位置从0的单链表
返回链表中第3个位置处,元素的值
LinkListNode*LinkList_Get(LinkList*list,intpos)
{
inti=0;
TLinkList*tList=(TLinkList*)list;
LinkListNode*current=NULL;
LinkListNode*ret=NULL;
if(list==NULL||pos<
0||pos>
=tList->
length)
{
returnNULL;
}
current=(LinkListNode*)tList;
for(i=0;
i<
pos;
i++)
current=current->
next;
ret=current->
returnret;
}
返回第三个位置的
移动pos次以后,当前指针指向哪里?
答案:
指向位置2,所以需要返回ret=current->
备注:
循环遍历时,遍历第1次,指向位置0
遍历第2次,指向位置1
遍历第3次,指向位置2
遍历第n次,指向位置n-1;
所以如果想返回位置n的元素的值,需要怎么做
ret=current->
此问题是:
指向头结点的指针移动n次和第n个元素之间的关系?
删除元素
无需一次性定制链表的容量
插入和删除操作无需移动数据元素
数据元素必须保存后继元素的位置信息
获取指定数据的元素操作需要顺序访问之前的元素
循环链表
循环链表的定义:
将单链表中最后一个数据元素的next指针指向第一个元素
循环链表拥有单链表的所有操作
创建链表
销毁链表
获取链表长度
清空链表
获取第pos个元素操作
插入元素到位置pos
删除位置pos处的元素
新增功能:
游标的定义
在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。
循环链表新操作
获取当前游标指向的数据元素
将游标重置指向链表中的第一个数据元素
将游标移动指向到链表中的下一个数据元素
直接指定删除链表中的某个数据元素
CircleListNode*CircleList_DeleteNode(CircleList*list,CircleListNode*node);
CircleListNode*CircleList_Reset(CircleList*list);
CircleListNode*CircleList_Current(CircleList*list);
CircleListNode*CircleList_Next(CircleList*list);
插入元素的分析
1)普通位置插入元素
2)添加第一个元素(第一次插入元素)
3)最后一个位置插入元素
4)第一个位置插入元素
在第一个位置插入
删除节点
功能强了。
循环链表只是在单链表的基础上做了一个加强
循环链表可以完全取代单链表的使用
循环链表的Next和Current操作可以高效的遍历链表中的所有元素
代码复杂度提高了
约瑟夫问题-循环链表典型应用
n个人围成一个圆圈,首先第1个人从1开始一个人一个人顺时针报数,报到第m个人,令其出列。
然后再从下一个人开始从1顺时针报数,报到第m个人,再令其出列,…,如此下去,求出列顺序。
双向链表
1、基本概念
单链表的结点都只有一个指向下一个结点的指针
单链表的数据元素无法直接访问其前驱元素
逆序访问单链表中的元素是极其耗时的操作!
len=LinkList_Length(list);
for(i=len-1;
len>
=0;
i++)//O(n)
{
LinkListNode*p=LinkList_Get(list,i);
//O(n)
//访问数据元素p中的元素
//
双向链表的定义
在单链表的结点中增加一个指向其前驱的pre指针
双向链表拥有单链表的所有操作
插入操作
删除操作
双向链表的新操作
将游标移动指向到链表中的上一个数据元素
DLinkListNode*DLinkList_DeleteNode(DLinkList*list,DLinkListNode*node);
DLinkListNode*DLinkList_Reset(DLinkList*list);
DLinkListNode*DLinkList_Current(DLinkList*list);
DLinkListNode*DLinkList_Next(DLinkList*list);
DLinkListNode*DLinkList_Pre(DLinkList*list);
//大家一定要注意:
教科书不会告诉你项目上如何用;
哪些点是项目的重点;
做一个企业级的财富库,完成你人生开发经验的积累,是我们的学习重点,要注意!
双向链表在单链表的基础上增加了指向前驱的指针
功能上双向链表可以完全取代单链表的使用
循环链表的Next,Pre和Current操作可以高效的遍历链表中的所有元素
代码复杂