2线性表.ppt_第1页
2线性表.ppt_第2页
2线性表.ppt_第3页
2线性表.ppt_第4页
2线性表.ppt_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2 线性表,2/49,线性表,主要知识点,顺序表,单链表,循环单链表,循环双向链表,应用举例,双链表,3/49,唯一头元素,唯一尾元素,除头元素外,均有一个直接前驱,除尾元素外,均有一个直接后继,2.1 线性表的概念,4/49,其中a1是头元素, an是尾元素, ai是第i个元素。,ai-1是ai的直接前驱, ai是ai-1的直接后继。,当2in时, ai有且只有一个直接前驱。,当1in-1时, ai有且只有一个直接后继。,2.1 线性表的概念,5/49,线性表的存储,顺序存储 顺序表 链式存储 链表,6/49,用一组地址连续的存储单元依次存储线性表的数据元素。,设每个元素需占用 l 个存储单

2、元,LOC(ai)表示元素ai的存储地址,则LOC(a1)是第一个数据元素a1的存储地址,也是整个线性表的起始地址,LOC(ai+1) = LOC(ai) + l,LOC(ai) = LOC(a1) + (i - 1)l,2.2 顺序表,7/49,算法2.1 在第 i 个数据元素之前插入一个新的元素,思想:,1. 将第 n 到 i 个元素均向后移动一个位置。,2. 将新元素放置在第 i 个位置。,例,在第 i 个元素前插入 b,b,8/49,例,在第4个元素之前插入元素25。,25,9/49,算法时间复杂度:,移动元素的个数取决于插入元素位置。,i=1,需移动 n 个元素;,i=i,需移动 n

3、 i +1 个元素;,i=n+1,需移动 0 个元素;,10/49,假设pi是在第 i 个元素之前插入一个新元素的概率,11/49,算法2.2 删除第 i 个数据元素,思想:,1. 删除第 i 个数据元素。,2. 将第 i+1 到 n 个元素均向前移动一个位置。,12/49,例,删除第4个元素25。,13/49,算法时间复杂度:,移动元素的个数取决于删除元素位置。,i=1,需移动n - 1个元素;,i=i,需移动n i 个元素;,i=n,需移动0个元素;,14/49,假设qi是删除第 i 个元素的概率,15/49,小结,顺序表中按位置读取元素十分方便,其时间代价为O(1); 其余操作包括插入、

4、删除和按内容查找的时间复杂度均为O(n)。,16/49,可随机存取表中任意数据元素,算法简单,空间单元利用率高;,优点:,直接可获取线性表的长度,例,L.elemi-1表示第 i 个数据元素,例,L.length表示线性表长度,缺点:,数据元素的插入、删除相对麻烦,需要预先确定数据元素的最大个数,插入和删除时需要移动较多的数据元素。,顺序表特点,17/49,2.3 链表(Linked List),通过指针来链接结点的存储方式。 利用指针来表示数据元素之间的逻辑关系 逻辑上相邻的元素在物理位置上不要求也相邻 按照需要为表中新的元素动态地分配存储空间,动态改变长度 根据链接方式和指针多寡 单链表

5、双链表 循环链表,18/49,链表的运算,检索: 在链表中查找满足某种条件的元素 插入 : 在链表的适当位置插入一个元素 删除: 从链表中删除一个指定元素,19/49,19,单链表(singly linked list),通过指针把它的一串存储结点链接成一个链 存储结点由两部分组成: 数据字段 + 指针字段(后继地址),20/49,20,单链表的存储结构,21/49,21,单链表的结点类型,template class Link public: T data; / 用于保存结点元素的内容 Link *next;/ 指向后继结点的指针 Link(const T info, const Link*

6、 nextValue = NULL) data = info; next = nextValue; Link(const Link* nextValue) next = nextValue; ;,22/49,22,单链表的定义,template class lnkList : public List private: Link * head, *tail; / 单链表的头、尾指针 Link *setPos(const int p);/ 返回线性表指向第p个元素的指针值 public: lnkList(int s);/ 构造函数 lnkList();/ 析构函数 bool isEmpty();

7、/ 判断链表是否为空 void clear(); / 将链表存储的内容清除,成为空表 int length(); / 返回此顺序表的当前实际长度 bool append(cosnt T value); / 在表尾添加一个元素value,表的长度增1 bool insert(cosnt int p, cosnt T value); / 在位置p上插入一个元素value,表的长度增1 bool delete(cosnt int p); / 删除位置p上的元素,表的长度减 1 bool getValue(cosnt int p, T/ 查找值为value的元素,返回第1次出现的位置 ,23/49,2

8、3,查找单链表中第i个结点,/ 函数返回值是找到的结点指针 template / 线性表的元素类型为T Link * lnkList : setPos(int i) int count = 0; if (i = -1) / i为-1则定位到头结点 return head; / 循链定位,若i为0则定位到第一个结点 Link *p = head-next; while (p != NULL /指向第 i 结点,i0,1,,当链表中结点数小于i时返回NULL ,24/49,24,单链表的插入,在23 和12 之间插入 10,创建新结点 新结点指向右边的结点 左边结点指向新结点,25/49,25,单

9、链表插入算法,/ 插入数据内容为value的新结点作为第i个结点 template / 线性表的元素类型为T bool lnkList : insert(const int i, const T value) Link *p, *q; if (p = setPos(i -1) = NULL) / p 是第i个结点的前驱 cout (value, p-next); /新节点指向右边节点 p-next = q; /左边节点指向新节点 if (p = tail)/ 插入点在链尾,插入结点成为新的链尾 tail = q; return true; ,26/49,26,x,p,p next = q ne

10、xt;,q,q = pnext;,free(q);,删除值为 x 的结点,27/49,27,template / 线性表的元素类型为T bool lnkList: delete(const int i) Link *p, *q; / 待删结点不存在,即给定的i大于当前链中元素个数 if (p = setPos(i-1) = NULL | p = tail) cout next;/ q是真正待删结点 if (q = tail) / 待删结点为尾结点,则修改尾指针 tail = p; p-next = NULL: delete q; else if (q != NULL) / 删除结点q 并修改链

11、指针p-next = q-next; delete q; return true; ,单链表删除算法,28/49,28,求长度算法,int length() Link *p = head-next; int count = 0; while (p != NULL) p = p-next; count+; return count; ,29/49,29,单链表上运算的分析,1. 对一个结点操作,必先找到它,即用一个指针指向它 2. 找单链表中任一结点,都必须从第一个点开始: p = head; while (没有到达) p = p-next;,单链表的时间复杂度 O(n) 定位: O(n) 插入

12、: O(1) 删除: O(1),30/49,30,双链表(double linked list),为弥补单链表的不足,而产生双链表 单链表的next字段仅仅指向后继结点,不能有效地找到前驱, 反之亦然 增加一个指向前驱的指针,31/49,31,双链表及其结点类型的说明,template class Link public: T data; / 用于保存结点元素的内容 Link * next;/ 指向后继结点的指针 Link *prev; / 指向前驱结点的指针 / 给定值和前后指针的构造函数 Link(const T info, Link* preValue = NULL, Link* nex

13、tValue = NULL) data = info; next = nextValue; prev = preValue; / 给定前后指针的构造函数 Link(Link* preValue = NULL, Link* nextValue = NULL) next = nextValue; prev = preValue; ,32/49,32,双链表的插入,如果要在p所指结点后插入一个新结点 执行new q开辟结点空间; 让该新结点的next填入p所指的后继地址; 新结点的prev填入p所指结点的后继的prev字段; new q; q-next = p- next; q-prev = p-

14、next -prev; 把新结点的地址填入原p所指结点的next字段; 新结点后继结点的prev字段也应该回指新结点 p- next = q; q- next -prev = q;,33/49,33,ki-1,ki,ki+1,p,pnext ,q,x,q prev = p;,q next = p next;,p next prev = q;,p next = q;,双链表插入示意,34/49,34,双链表的删除,如果要删除指针变量 p 所指的结点,只需修改该结点前驱的 next 字段和该结点后继的prev字段,即 p- prev - next = p- next; p- next - prev

15、 = p- prev; 然后把变量p变空,把p所指空间释放即可 p- next = NULL; p-prev = NULL; delete p;,35/49,35,ki-1,ki,ki+1,p,p prev ,p next ,p prev next = p next,p next prev = p prev,prev,next,双链表删除示意,36/49,36,循环链表(circularly linked list),将单链表或者双链表的头尾结点链接起来,就是一个循环链表 不增加额外存储花销,却给不少操作带来了方便 从循环表中任一结点出发,都能访问到表中其他结点,37/49,37,几种链表比较

16、,38/49,38,链表的边界条件,几个特殊点的处理 头指针处理 非循环链表尾结点的指针域保持为NULL 循环链表尾结点的指针回指头结点 链表处理 空链表的特殊处理 插入或删除结点时指针勾链的顺序 指针移动的正确性 插入 查找或遍历,39/49,39,线性表实现方法的比较,顺序表的主要优点 没有使用指针,不用花费额外开销 线性表元素的读访问非常简洁便利 链表的主要优点 无需事先了解线性表的长度 允许线性表的长度动态变化 能够适应经常插入删除内部元素的情况,顺序表是存储静态数据的不二选择 链表是存储动态变化数据的良方,40/49,40,顺序表和链表的比较,顺序表 插入、删除运算时间代价O(n),

17、按位置查找则可常数时间完成 预先申请固定长度的数组 如果整个数组元素很满,则没有结构性存储开销 链表 插入、删除运算时间代价O(1),但找第i个元素运算时间代价O(n) 存储利用指针,动态地按照需要为表中新的元素分配存储空间 每个元素都有结构性存储开销,41/49,41,顺序表和链表存储密度,n表示线性表中当前元素的数目, P表示指针的存储单元大小(通常为4bytes) E表示数据元素的存储单元大小 D表示可以在数组中存储的线性表元素的最大数目 空间需求 顺序表的空间需求为DE 链表的空间需求为n(P+E) n的临界值,即n DE/(P+E) n越大,顺序表的空间效率就更高 如果P = E,则

18、临界值为n = D/2,42/49,42,应用场合的选择,顺序表不适用的场合 经常插入删除时,不宜使用顺序表 线性表的最大长度也是一个重要因素 链表不适用的场合 当读操作比插入删除操作频率大时,不应选择链表 当指针的存储开销,和整个结点内容所占空间相比其比例较大时,应该慎重选择,43/49,43,顺序表和链表的选择,顺序表 结点总数目大概可以估计 线性表中结点比较稳定(插入删除少) n DE/(P+E) 链表 结点数目无法预知 线性表中结点动态变化(插入删除多) n DE/(P+E),44/49,44,小结,44,顺序表 按索引值从小到大存放在一片相邻的连续区域 紧凑结构,存储密度为1 链表 单链表 双链表 循环链表,45/49,应用-跳舞链(Dancing Links),A,C,B,1. p-prev-next = p-next ;,2. p-next-prev = p-prev ;,如何恢复到链表中呢?,操作 (1),操作 (2),注意到删除p结点时,我们未将p结点的左右指针清空,那么将p恢复到链表的操作将变得与(1)操作一样简单: p-prev-next = p, p-next-prev = p。,46/49,Dancing Li

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论