1 / 15

2 、线性表

2 、线性表. 1 、线性结构的定义:. 空或者只有一个结点。或者 1 、存在唯一的一个被称之为”第一个“ 的结点。 2 、存在唯一的一个被称之为”最后一个“ 的结点。 3 、除第一个结点之外,每个结点均只有一个前驱结点。 4 、除最后一个结点之外,每个结点均只有一个后继结点。 分为以下几大类: · 线性表: 进通过它们之间的相对位置,确定它们之间的相互关系的线性结构。 e.g: 序列: a 1 、 a 2 、 a 3 …………………a n-1 、 a n · 分类表 · 时间有序表 · 频率有序表 · 序列. 2 、线性表.

maree
Download Presentation

2 、线性表

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 2、线性表 • 1、线性结构的定义: • 空或者只有一个结点。或者 1、存在唯一的一个被称之为”第一个“ 的结点。 • 2、存在唯一的一个被称之为”最后一个“ 的结点。 • 3、除第一个结点之外,每个结点均只有一个前驱结点。 • 4、除最后一个结点之外,每个结点均只有一个后继结点。 • 分为以下几大类: • ·线性表:进通过它们之间的相对位置,确定它们之间的相互关系的线性结构。 • e.g: 序列:a1、 a2、 a3…………………an-1、 an • ·分类表 • ·时间有序表 • ·频率有序表 • ·序列

  2. 2、线性表 • 2、基本操作:插入、删除、查找 …… • e.g:已知线性表 LA 和线性表 LB 中的结点为递增序。将 LA 和 LB 进行合并至 • 另一线性表 LC, 并仍为递增序。 • LA = (3,5,8,11) LB = (2,6,8,9,11,15,20) • LC = (2,3,5,6,8,8,9,11,11,15,20) Void Mergelist(List La,list Lb, list & Lc) { InitiList( Lc ); i=j=1; k=0; La.len = ListLength(La); Lb.len = ListLength(Lb); while ( ( i <= La.len ) && ( j <= Lb.len ) ) { GetElem(La,i,ai); GetElem(Lb,j,bj); if (ai <= bj ) { Listinsert(Lc, ++k, ai ) ; ++i; } else { Listinsert(Lc, ++k, bj ) ; ++j; } } while (i <= La.len) { GetElem(La,i,ai); Listinsert(Lc, ++k, ai ) ; ++i; }; while (j <= Lb.len) { GetElem(Lb,j,bj); Listinsert(Lc, ++k, bj ) ; ++j; }; } // Mergelist La Lb • 时间复杂性: O( m + n )

  3. 2、线性表 • 3、物理存储位置的计算: ·顺序表示:在物理位置上紧靠在一起。如用数组表示线性表。 • ·设第一个结点的存储地址为 LOC(a1), 余类推。设每个结点占用 L 个单元。则: • LOC(ai) = LOC(ai-1) + L • = LOC(ai-2) + 2L • = LOC(ai-(i-1)) + (i-1)L • = LOC(a1) + (i-1)L a1 a2 ai-1 ai an

  4. 2、线性表 • 4、插入的时间复杂性分析: • 在一般情况下,插在第 i 个结点之前,移动 n-(i-1) 次 • 插在第 1 个结点之前,移动 n 次 • 插在第 2 个结点之前,移动 n-1 次 • 插在第 i 个结点之前,移动 n-(i-1) 次 • 插在第 n 个结点之前,移动 1 次。 • 插在第 n 个结点之后,移动 0 次。 总共 n+1 种情况 • ·在长度为 n 的顺序表示的线性表中插入一个结点的平均次数为: • ∑(n-i+1)/(n+1) = n/2 时间复杂性为 O(n)。 n i =1

  5. 2、线性表 • 5、删除的时间复杂性分析: • 在一般情况下,删除第 i 个结点,移动 n-i 次 • 删除第 1 个结点,移动 n-1 次 • 删除第 2 个结点,移动 n-2 次 • 删除第 i 个结点,移动 n-i 次 • 删除第 n 个结点,移动 0 次。 总共 n 种情况 • ·在长度为 n 的顺序表示的线性表中删除一个结点的平均次数为: • ∑(n-i)/n = (n-1)/2 时间复杂性为 O(n)。 n i =1 • ·另外,通过 KEY 查找结点,代价 O(n)。 • 查找第 i 个结点,代价O(1)。

  6. data next data next L 头结点:不是线性表 之中的结点。但增加 此结点后,操作容易。 A H A B B Z ∧ Z ∧ 2、线性表 • 6、线性链表(单链接表): • · 结点的表示:参照下图所示的情况: typedef struct Lnode { ElemType dat a; struct Lnode * next; } Lnode, * LinkList; • · 单链接表的表示:参照下图所示的情况: 其中H 是表首指针。

  7. 2、线性表 • 6、线性链表(单链接表): • · 和顺序表示的线性表的操作的比较: 插入: O(1) 删除: O(1) FINDith: O(i) 平均 O(n) FINDkey : 平均 O(n) 插入: O(n) 删除: O(n) FINDith: O(1) FINDkey : 平均 O(n) 单链表 顺序存储的线性表

  8. 2、线性表 • 7、静态链表的使用 • 目的:在顺序存储(数组)的情况下,利用链表的插、删操作快速功能。 • 使用环境:用于不支持动态存储分配功能的语言。当然也可用于支持动态存储分配功 • 能的语言。 • 缺点:必须预估存区的大小,造成浪费。 • 手段:采用备用链或空闲栈实现。使用者必须自己编写分配单元和回收无用单元的操 作。使用单元时,自备用链分配。无用单元被回收到备用链。 data cur data cur 0 1 data cur 2 space[0] 1 space[1] 2 3 4 5 space[2] 3 space[3] 6 4 space[4] -1 5 space[5] 6 space[6] -1

  9. 2、线性表 • 将用作存储空间的数组的所有单元分配至空闲栈或备用链。 void InitSpace_SL(SLinkList & Space) { for ( i=0; i < MAXSIZE -1; ++i ) space[i].cur = i+1; space[MAXSIZE-1] = 0; } • 从空闲栈或备用链得到可用的数组单元,其下标为 i。 int Malloc_SL(SLinkList &Space) { i = space[0].cur; if ( space[0].cur); space[0].cur = space[i].cur; return i; } • 将下标为 k 的无用的数组单元回收至空闲栈或备用链。 int free_SL(SLinkList &Space, int k) { space[k].cur = space[0].cur; space[0].cur = k; }

  10. 2、线性表 • 8、双向链表: • · 特点:结点的有两个指针场用于指向本结点的前驱结点和后继结点。前驱结点的后继结 点和后继结点的前驱结点都是本结点。知道了本结点的地址就可以把它删除。 L typedef struct duLnode { ElemType data; struct duLnode * prior; struct duLnode * next; } duLnode, * duLinkList;

  11. 2、线性表 • 8、双向链表: • · 删除:给出待删结点的地址就可以把它删除。如;删除数据场之值为 a 的结点,地址由 p 给出。 L a b c p 执行:p->prior->next = p->next ; 执行:p->next->prior = p->prior ; 最后执行: free(p) 查找:可从两头开始。代价从平均 n/2 降低为 n/4。

  12. s 2、线性表 • 8、双向链表: • · 插入:注意插入次序。如:将数据场为 x 的结点,插在由指针 p 指向的结点之后。 p L a b c x ·s->prior = p; ·s->next = p->next; ·p->next->prior = s; ·p->next = s;

  13. 2、线性表 • 例如:一元多项式的表示及相加; • ·如:多项式: PA = 7+3x+9x8+5x17 PB = 8x+22x7-9x8 typedef struct Lnode { ElemType data; struct Lnode * next; } Lnode, * LinkList; typedef struct { flost coef; int expn; } term, ElemType; coef expn next PA ∧ 7 0 3 1 9 8 5 17 PB ∧ 8 1 22 7 -9 8 PC 7 0 11 1 227 ∧ 5 17 • ·算法:指数等:若系数之和为零,则两首结点都删除。否则, 将系数为两者之和以及 指数为原指数的新结点放入 PC 链尾, 原两结点也删除, PA首结点指数小: 删除PA首结点,将其放入 PC 链尾。 • PB首结点指数小: 删除PB首结点,将其放入 PC 链尾。 • 注意: 二个多项式的中的多余部分,插入PC 链尾。

  14. 2、线性表 • 问题:在考虑成功和失败两种情况下,顺序存储的线形表的平均查找长度? • 问题:原单链表如下图所示。请将所有的链接指针全部颠倒。 next h ∧ { point newh, p; { newh = NULL; while ( h < > NULL ) { p = h; ; p-> next = newh; newh = p; } ; 【 】 h = newh; } } 该语句为 h = p ->next

  15. 1.s->prior->next = s->next 2.s->next->prior = s->prior 3.s->prior = h->prior 4.s->next = h 5. h->prior->next =s 6. h->prior = s 2、线性表 问题: :把 L A B C D L B A C D = ( , , , )转化为 = ( , , , ),注意必须先删除数 B A 据场为 的节点,再将其插入到 数据场为 的节点之前,请给出具体的操作 s h -> next; h s 步骤。设 = 除 、 外,不许增加其它的变量。 B 第一步:先删除数据场为 的节点的具体的操作步骤: B A 第二步:将数据场为 的节点插入到数据场为 的节点之前的操作步骤: s h 双链表初态: A B C D

More Related