《数据结构C语言版》第02章_第1页
《数据结构C语言版》第02章_第2页
《数据结构C语言版》第02章_第3页
《数据结构C语言版》第02章_第4页
《数据结构C语言版》第02章_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

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

文档简介

1、数据结构C语言版第02章 第第2 2章章 线性表线性表 主要知识点主要知识点 线性表抽象数据类型线性表抽象数据类型 顺序表顺序表 循环单链表循环单链表 循环双向链表循环双向链表 静态链表静态链表 设计举例设计举例 数据结构C语言版第02章 2.12.1 线性表抽象数据类型线性表抽象数据类型 1.1.线性表的定义线性表的定义 线性表是一种可以在任意位置插入和删除数线性表是一种可以在任意位置插入和删除数 据元素操作、由据元素操作、由n(n0)个相同类型数据元素个相同类型数据元素a0, a1, an-1组成的线性结构。组成的线性结构。 数据结构C语言版第02章 2.2.线性表抽象数据类型线性表抽象数

2、据类型 数据集合数据集合: a0, a1, , an-1 , ai的数据类型为的数据类型为DataType 操作集合操作集合: (1) ListInitiate(L) 初始化线性表初始化线性表 (2) ListLength(L) 求当前数据元素个数求当前数据元素个数 (3) ListInsert(L,i,x) 插入数据元素插入数据元素 (4) ListDelete(L,i,x) 删除数据元素删除数据元素 (5) ListGet(L,i,x) 取数据元素取数据元素 数据结构C语言版第02章 2.22.2 线性表的顺序表示和实现线性表的顺序表示和实现 1.顺序表的存储结构顺序表的存储结构 实现顺序

3、存储结构的方法是使用数组。数组把线性表的实现顺序存储结构的方法是使用数组。数组把线性表的 数据元素存储在一块连续地址空间的内存单元中,这样线性数据元素存储在一块连续地址空间的内存单元中,这样线性 表中逻辑上相邻的数据元素在物理存储地址上也相邻。数据表中逻辑上相邻的数据元素在物理存储地址上也相邻。数据 元素间的逻辑上的前驱、后继逻辑关系就表现在数据元素的元素间的逻辑上的前驱、后继逻辑关系就表现在数据元素的 存储单元的物理前后位置上。存储单元的物理前后位置上。 顺序表的存储结构如图所示顺序表的存储结构如图所示 顺序存储结构的顺序存储结构的线性表称作顺序表线性表称作顺序表 数据结构C语言版第02章

4、a0a1a2a3a4a5 list size=6 MaxSize-1 0 1 2 3 4 5 6 其中其中a0 ,a1, a2等表示顺序表中存储的数据元素,等表示顺序表中存储的数据元素,list表示表示 顺序表存储数据元素的数组,顺序表存储数据元素的数组,MaxSize表示存储顺序表的数表示存储顺序表的数 组的最大存储单元个数,组的最大存储单元个数,size表示顺序表当前存储的数据元表示顺序表当前存储的数据元 素个数。素个数。 typedef struct DataType listMaxSize; int size; SeqList; 数据结构C语言版第02章 2.顺序表操作的实现顺序表操作

5、的实现 (1)初始化)初始化ListInitiate(L) void ListInitiate(SeqList *L) L-size = 0;/*定义初始数据元素个数定义初始数据元素个数*/ (2)求当前数据元素个数)求当前数据元素个数ListLength(L) int ListLength(SeqList L) return L.size; 数据结构C语言版第02章 (3)插入数据元素插入数据元素ListInsert(L, i, x) int ListInsert(SeqList *L, int i, DataType x) int j; for(j = L-size; j i; j-) L

6、-listj = L-listj-1; / /* *依次后移依次后移* */ / L-listi = x; /*插入插入x*/ L-size +; /*元素个数加元素个数加1*/ return 1; 数据结构C语言版第02章 101112141516list list MaxSize-1 0123456 i=3 Size=6 size=7 13待插数据 x 7 10111213141516 MaxSize-1 01234567 i=3size=6 . . 数据结构C语言版第02章 (4 4)删除数据元素删除数据元素ListDelete(L, i, x)ListDelete(L, i, x) i

7、nt ListDelete(SeqList *L, int i, DataType *x) int j; *x = L-listi;/ /* *保存删除的元素到保存删除的元素到x x中中* */ / for(j = i +1; j size-1; j+) L-listj-1 = L-listj; / /* *依次前移依次前移* */ / L-size-;/ /* *数据元素个数减数据元素个数减1 1* */ / return 1; 数据结构C语言版第02章 10111213141516list 删 除 前 101112141516list 删 除 后 MaxSize-1 01234 56 Ma

8、xSize-1 0123456 i=3 size=7 size=6 要 删 的 数 据 x13 . . 数据结构C语言版第02章 (5 5)取数据元素)取数据元素ListGet(L, i, x)ListGet(L, i, x) int ListGet(SeqList L, int i, DataType *x) if(i L.size-1) printf(参数参数i不合法不合法! n); return 0; else *x = L.listi; return 1; 数据结构C语言版第02章 3.顺序表操作的效率分析顺序表操作的效率分析 时间效率分析时间效率分析: 算法时间主要耗费在移动元素的操

9、作上,因此计算时间复算法时间主要耗费在移动元素的操作上,因此计算时间复 杂度的基本操作杂度的基本操作(最深层语句频度最深层语句频度) T(n)= O(移动元素次数移动元素次数) 而移动元素的个数取决于插入或删除元素的位置而移动元素的个数取决于插入或删除元素的位置i. 若若i=size,则根本无需移动(特别快);则根本无需移动(特别快); 若若i=0,则表中元素全部要后移(特别慢);则表中元素全部要后移(特别慢); 应当考虑在各种位置插入(共应当考虑在各种位置插入(共n+1种可能)的平均移动次种可能)的平均移动次 数才合理。数才合理。 数据结构C语言版第02章 设设Pi是在第是在第i个存储位置插

10、入一个数据元素的概率,顺序表个存储位置插入一个数据元素的概率,顺序表 中的数据元素个数为中的数据元素个数为n,当在顺序表的任何位置上插入数据当在顺序表的任何位置上插入数据 元素的概率相等时,有元素的概率相等时,有Pi=1/(n+1),则则 插入时的平均移动次数为插入时的平均移动次数为: : n(n+1)/2(n+1)n/2 同理可证同理可证: :顺序表删除一元素的时间效率为顺序表删除一元素的时间效率为: : T(n)=(n-1)/2 数据结构C语言版第02章 插入效插入效 率:率: 删除效删除效 率:率: 00 1 ()() 12 nn isi ii n Ep nini n 11 00 11

11、()() 2 nn dli ii n Eq nini n 数据结构C语言版第02章 顺序表中的其余操作都和数据元素个数顺序表中的其余操作都和数据元素个数n无关,因此,在无关,因此,在 顺序表中插入和删除一个数据元素的时间复杂度为顺序表中插入和删除一个数据元素的时间复杂度为O(n),其余其余 操作的时间复杂度都为操作的时间复杂度都为O(1) 主要优点是算法简单,空间单元利用率高;主要优点是算法简单,空间单元利用率高; 主要缺点是需要预先确定数据元素的最大主要缺点是需要预先确定数据元素的最大 个数,插入和删除时需要移动较多的数据个数,插入和删除时需要移动较多的数据 元素。元素。 主要优缺点主要优缺

12、点 数据结构C语言版第02章 4.顺序表应用举例顺序表应用举例 例:编程实现如下任务例:编程实现如下任务: :建立一个线性表,首先依次建立一个线性表,首先依次 输入数据元素输入数据元素1 1,2 2,3 3,1010,然后删除数据元素,然后删除数据元素5 5,最,最 后依次显示当前线性表中的数据元素。要求采用顺序表实后依次显示当前线性表中的数据元素。要求采用顺序表实 现,假设该顺序表的数据元素个数在最坏情况下不会超过现,假设该顺序表的数据元素个数在最坏情况下不会超过 100100个。个。 数据结构C语言版第02章 实现方法:实现方法: 1 1、采用直接编写一个主函数实现。、采用直接编写一个主函

13、数实现。 2 2、利用已设计实现的抽象数据类型模块。(存放在头文件名、利用已设计实现的抽象数据类型模块。(存放在头文件名 为为SeqList.hSeqList.h中,通过中,通过 # #include “SeqList.h” include “SeqList.h” ) 程序设计如下:程序设计如下: #include #define MaxSize 100 typedef int DataType; #include SeqList.h 数据结构C语言版第02章 void main(void) SeqList myList; int i , x; ListInitiate( for(i = 0;

14、 i 10; i+) ListInsert( ListDelete( for(i = 0; i next = NULL;head)-next = NULL; 数据结构C语言版第02章 (2 2)求当前数据元素个数求当前数据元素个数ListLength(head)ListLength(head) int ListLength(SLNode *head) SLNode *p = head; int size = 0; while(p-next != NULL) p = p-next; size +; return size; 数据结构C语言版第02章 head. 0 a 1 a 1n a size

15、=0 (a) . 0 a 1 a 1n a size=n (b) p p head 数据结构C语言版第02章 (3 3)插入插入ListInsert(head, i, x)ListInsert(head, i, x) int ListInsert(SLNode *head, int i, DataType x) SLNode *p, *q; int j; p = head; j = -1; while(p-next != NULL j+; if(j != i - 1) printf(“插入位置参数错!插入位置参数错!”); return 0; q = (SLNode *)malloc(size

16、of(SLNode); q-data = x; q-next = p-next; p-next = q; return 1; 数据结构C语言版第02章 0 a. i a 1n a qx . 1i a 0 a . i a 1n a . 1i a xq (a) (c) (b) p p head head 数据结构C语言版第02章 说明:要在带头结点的单链表第说明:要在带头结点的单链表第i i(0 i size0 i size) 个结点前插入一个存放数据元素个结点前插入一个存放数据元素x x的结点,首先要在单链的结点,首先要在单链 表中寻找到第表中寻找到第i-1i-1个结点并由指针个结点并由指针p

17、p指示,然后动态申请指示,然后动态申请 一个结点存储空间并由指针一个结点存储空间并由指针q q指示,并把数据元素指示,并把数据元素x x的值的值 赋予新结点的数据元素域(即赋予新结点的数据元素域(即q-data = xq-data = x),),最后修改最后修改 新结点的指针域指向新结点的指针域指向a ai i结点(即结点(即q-next = p-nextq-next = p-next),), 并修改并修改a ai-1 i-1结点的指针域指向新结点 结点的指针域指向新结点q q(即即p-next = qp-next = q)。)。 循环条件由两个子条件逻辑与组成,其中子条件循环条件由两个子条件

18、逻辑与组成,其中子条件p-p- next != NULLnext != NULL保证指针所指结点存在,子条件保证指针所指结点存在,子条件j i - j next != NULL j+; if(j != i - 1) if(j != i - 1) printf(“ printf(“插入位置参数错!插入位置参数错!”);); return 0; return 0; s = p-next; *x = s-data; p-next = p-next-next; free(s); return 1; 数据结构C语言版第02章 0 a. i a 1n a . 1i a (a) 0 a. 1n a . 1i

19、 a (b) i ai a s head head p 1i a 1i a p 说明:要在带头结点的单链表中删除第说明:要在带头结点的单链表中删除第i i(0 i size - 10 i size - 1) 个结点,首先要在单链表中寻找到第个结点,首先要在单链表中寻找到第i-1i-1个结点并由指针个结点并由指针p p指示,指示, 然后让指针然后让指针s s指向指向a ai i结点(即结点(即s = p-nexts = p-next),),并把数据元素并把数据元素a ai i 的值赋予的值赋予x x(即即* *x = s-datax = s-data),),最后把最后把a ai i结点脱链(即结

20、点脱链(即p-p- next = p-next-nextnext = p-next-next),),并动态释放并动态释放a ai i结点的存储空间(即结点的存储空间(即 free(s)free(s))。)。删除过程如图删除过程如图2-142-14所示。图中的对应算法中的删所示。图中的对应算法中的删 除语句。除语句。 数据结构C语言版第02章 (5 5)取数据元素)取数据元素ListGet(head, i, x)ListGet(head, i, x) int ListGet(SLNode *head, int i, DataType *x) SLNode *p; int j; p = head;

21、 j = -1; while(p-next != NULL j+; if(j != i) printf(“取元素位置参数错!取元素位置参数错!”); return 0; *x = p-data; return 1; 数据结构C语言版第02章 (6 6)撤消单链表撤消单链表Destroy(head)Destroy(head) void Destroy(SLNode *head) SLNode *p, *p1; p = *head; while(p != NULL) p1 = p; p = p-next; free(p1); *head = NULL; 数据结构C语言版第02章 00 1 ()()

22、 12 nn isi ii n Ep nini n 11 00 11 ()() 2 nn dli ii n Eq nini n 4.单链表操作的效率分析单链表操作的效率分析 单链表的插入和删除操作不需移动数据元素,只需比较数据单链表的插入和删除操作不需移动数据元素,只需比较数据 元素。因此,当在单链表的任何位置上插入数据元素的概率元素。因此,当在单链表的任何位置上插入数据元素的概率 相等时,在单链表中插入一个数据元素时比较数据元素的平相等时,在单链表中插入一个数据元素时比较数据元素的平 均次数为:均次数为: 删除一个数据元素时比较数据元素的平均次数为:删除一个数据元素时比较数据元素的平均次数为

23、: 另外,单链表求数据元素个数操作的时间复杂度为另外,单链表求数据元素个数操作的时间复杂度为O(n)。 数据结构C语言版第02章 和顺序表相比和顺序表相比 主要优点是不需要预先确定数据元素的最大主要优点是不需要预先确定数据元素的最大 个数,插入和删除操作不需要移动数据元素;个数,插入和删除操作不需要移动数据元素; 主要缺点是因为是顺序存储结构,所以,查主要缺点是因为是顺序存储结构,所以,查 找数据元素时需要顺序进行,不能像顺序表找数据元素时需要顺序进行,不能像顺序表 那样随机查找任意一个数据元素。另外,每那样随机查找任意一个数据元素。另外,每 个结点中要有一个指针域,因此空间单元利个结点中要有

24、一个指针域,因此空间单元利 用率不高。而且单链表操作的算法也较复杂。用率不高。而且单链表操作的算法也较复杂。 单链表单链表 和单链表相比,顺序表的优点和缺点正好相反。和单链表相比,顺序表的优点和缺点正好相反。 数据结构C语言版第02章 5.单链表应用举例单链表应用举例 例:编程实现如下任务例:编程实现如下任务: :建立一个线性表,首先依次输入建立一个线性表,首先依次输入 数据元素数据元素1 1,2 2,3 3,1010,然后删除数据元素,然后删除数据元素5 5,最后依次,最后依次 显示当前线性表中的数据元素。要求采用单链表实现。显示当前线性表中的数据元素。要求采用单链表实现。 #include

25、 #include #include typedef int DataType; #include LinList.h 数据结构C语言版第02章 void main(void) SLNode *head; int i , x; ListInitiate( for(i = 0; i 10; i+) ListInsert(head, i, i+1) ; ListDelete(head, 4, for(i = 0; i !=NULL改为改为 p-!=head 数据结构C语言版第02章 2.5 2.5 双向链表双向链表 双向链表是每个结点除后继指针域外还有一个前驱指双向链表是每个结点除后继指针域外还有

26、一个前驱指 针域,它有带头结点和不带头结点,循环和非循环结构,针域,它有带头结点和不带头结点,循环和非循环结构, 双向链表是解决查找前驱结点问题的有效途径。双向链表是解决查找前驱结点问题的有效途径。 结点结构如图示:结点结构如图示: prior data next 下图是带头结点的循环双向链表的结构,可见,其前驱指下图是带头结点的循环双向链表的结构,可见,其前驱指 针和后继指针各自构成自己的循环单链表。针和后继指针各自构成自己的循环单链表。 数据结构C语言版第02章 head (a) 空链表空链表 a0a1an-1 head (b) 非空链表非空链表 在双向链表中在双向链表中: 设指针设指针p

27、指向第指向第i个数据元素结点,则个数据元素结点,则p-next指向第指向第i+1 个数据元素结点,个数据元素结点,p-next-prior仍指向第仍指向第i个数据元素结点,个数据元素结点, 即即p-next-prior=p;同样同样p-prior-next=p。 数据结构C语言版第02章 循环双向链表的插入过程如图示:循环双向链表的插入过程如图示: a0aian-1 head xs ai-1 p 删除过程如图示:删除过程如图示: ai+1aian-1 head ai-1 p 数据结构C语言版第02章 2.6 2.6 静态链表静态链表 在数组中增加一个在数组中增加一个(或两个或两个)指针域用来存

28、放下一个指针域用来存放下一个(或上一个或上一个) 数据元素在数组中的下标,从而构成用数组构造的单链表。数据元素在数组中的下标,从而构成用数组构造的单链表。 因为数组内存空间的申请方式是静态的,所以称为静态链表,因为数组内存空间的申请方式是静态的,所以称为静态链表, 增加的指针称做仿真指针。结构如下:增加的指针称做仿真指针。结构如下: ABCE head D (a) 常规链表常规链表 数据结构C语言版第02章 A1 B2 C3 D4 E-1 (b) 静态链表静态链表1 data next 0 1 2 3 4 maxSize-1 A2 E-1 B4 D1 C3 (b) 静态链表静态链表2 data

29、 next 0 1 2 3 4 maxSize-1 数据结构C语言版第02章 2.7 2.7 设计举例设计举例 例例2-4 设计一个顺序表的删除函数,把顺序表设计一个顺序表的删除函数,把顺序表L中的数据元中的数据元 素素x删除。删除。 算法思想:此删除问题可通过一个循环比较过程来实算法思想:此删除问题可通过一个循环比较过程来实 现。现。 数据结构C语言版第02章 int ListDataDelete(SeqList *L, DataType x) int i, j; for(i = 0; i size; i+) if(x = L-listi) break; if(i = L-size) ret

30、urn 0; else for(j = i; j size; j+) L-listj = L-listj+1; L-size-; return 1; 数据结构C语言版第02章 例例2-5 构造一个顺序表的删除算法,把顺序表构造一个顺序表的删除算法,把顺序表L中所有值相中所有值相 同的数据元素同的数据元素x全部删除。全部删除。 算法思想:此删除问题是在例算法思想:此删除问题是在例2-4所设计的删除算法的所设计的删除算法的 基础上再增加一重循环,来实现值相同数据元素基础上再增加一重循环,来实现值相同数据元素x的全部删的全部删 除。除。 数据结构C语言版第02章 int ListMoreDataDe

31、lete(SeqList *L, DataType x) int i, j; int tag = 0; for(i = 0; i size; i+) if(x = L-listi) for(j = i; j size-1; j+) L-listj = L-listj+1; L-size-; i-; tag = 1; return tag; 数据结构C语言版第02章 例例2-6设头指针为设头指针为head,并设带头结点单链表中的数据元素并设带头结点单链表中的数据元素 递增有序,编写算法将数据元素递增有序,编写算法将数据元素x插入到带头结点单链表的插入到带头结点单链表的 适当位置上,要求插入后保持

32、单链表数据元素的递增有序。适当位置上,要求插入后保持单链表数据元素的递增有序。 算法思想:从链表的第一个数据元素结点开始,逐个比较算法思想:从链表的第一个数据元素结点开始,逐个比较 每个结点的每个结点的data域值和域值和x的值,当的值,当data小于等于小于等于x时,进行时,进行 下一个结点的比较;否则就找到了插入结点的合适位置,下一个结点的比较;否则就找到了插入结点的合适位置, 此时申请新结点把此时申请新结点把x存入,然后把新结点插入;当比较到最存入,然后把新结点插入;当比较到最 后一个结点仍有后一个结点仍有data小于等于小于等于x时,则把新结点插入单链表时,则把新结点插入单链表 尾。尾

33、。 数据结构C语言版第02章 void LinListInsert(SLNode *head, DataType x) SLNode *curr, *pre, *q; curr = head-next; pre = head; while(curr != NULL q = (SLNode *)malloc(sizeof(SLNode); q-data = x; q-next = pre-next; pre-next = q; 数据结构C语言版第02章 算法设计说明:算法设计说明: (1)在循环定位插入位置时,循环条件必须首先是)在循环定位插入位置时,循环条件必须首先是curr != NULL,然后是然后是curr-data data不

温馨提示

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

评论

0/150

提交评论