第3章 线性表的链式存储
线性表 知识点总结

线性表知识点总结线性表的特点:1. 有序性:线性表中的元素是有序排列的,每个元素都有唯一的前驱和后继。
2. 可变性:线性表的长度是可变的,可以进行插入、删除操作来改变表的元素数量。
3. 线性关系:线性表中的元素之间存在明确的前驱和后继关系。
4. 存储结构:线性表的存储结构有顺序存储和链式存储两种方式。
线性表的操作:1. 查找操作:根据元素的位置或值来查找线性表中的元素。
2. 插入操作:将一个新元素插入到线性表中的指定位置。
3. 删除操作:将线性表中的某个元素删除。
4. 更新操作:将线性表中的某个元素更新为新的值。
线性表的顺序存储结构:顺序存储结构是将线性表的元素按照其逻辑顺序依次存储在一块连续的存储空间中。
线性表的顺序存储结构通常采用数组来实现。
数组中的每个元素都可以通过下标来访问,因此可以快速的进行查找操作。
但是插入和删除操作会导致元素位置的变动,需要进行大量数据搬移,效率较低。
线性表的链式存储结构:链式存储结构是将线性表的元素通过指针相连,形成一个链式结构。
每个元素包含数据和指向下一个元素的指针。
链式存储结构不需要连续的存储空间,可以动态分配内存,适合插入和删除频繁的场景。
但是链式结构的元素访问不如顺序结构高效,需要通过指针来逐个访问元素。
线性表的应用场景:1. 线性表适用于数据元素之间存在明确的前后关系,有序排列的场景。
2. 顺序存储结构适用于元素的插入和删除操作较少,对元素的随机访问较频繁的场景。
3. 链式存储结构适用于插入和删除操作较频繁的场景,对元素的随机访问较少。
线性表的操作的时间复杂度:1. 查找操作:顺序存储结构的时间复杂度为O(1),链式存储结构的时间复杂度为O(n)。
2. 插入和删除操作:顺序存储结构的时间复杂度为O(n),链式存储结构的时间复杂度为O(1)。
线性表的实现:1. 顺序存储结构的实现:使用数组来存储元素,通过下标来访问元素。
2. 链式存储结构的实现:使用链表来实现,每个元素包含数据和指向下一个元素的指针。
线性表的链式存储

序号 0 1 2
数据域 邓玉莹配送信息 魏秀婷配送信息 刘佳佳配送信息
指针域 1 -1 0
…
…
…
任务2:静态链表存储结构举例并采用C语言定义
3.1.4 动态链表的实现
Head
刘佳佳配送信息 ^
Head
Head
刘佳佳配送信息
邓玉莹送信息
魏秀婷配送信息
动态链表结点定义一般形式: typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
4.定义链表变量两种定义形式: (1)LinkList Head; (2)LNode *Head;
【知识拓展】: 指针变量和结点变量的关系
(1)生成结点变量的标准函数 p=( LNode *)malloc(sizeof(LNode)); //函数malloc分配一个类型为ListNode的结点变量的空间, 并将其首地址放入指针变量p中。 (2)释放结点变量空间的标准函数 free(p); //释放p所指的结点变量空间。 (3)结点分量的访问 利用结点变量的名字*p访问结点分量 方法一:(*p).data和(*p).next 方法二:p-﹥data和p-﹥next (4)指针变量p和结点变量*p的关系 指针变量p的值——结点地址 结点变量*p的值——结点内容 (*p).data的值——p指针所指结点的data域的值 (*p).next的值——*p后继结点的地址 *((*p).next)——*p后继结点
问题思考:总结链式存储结构的特点
单链表定义的一般形式: 由分别表示a1,a2,…,an, 的n 个结点依次相链构成的链表,称为线性表的 链式存储表示,由于此类链表的每个结点中只包含一个指针域,故称为 单链表或线性链表。
第三章 线性表习题

第三章 线性表填空题1.线性表的顺序存储结构通过 来直接反映数据元素之间的逻辑关系,而链式存储结构通过 间接反映数据元素之间的逻辑关系。
2.在线性表的顺序存储结构中,逻辑位置相邻的数据元素在 上也相邻,而链式存储结构中,逻辑位置相邻的数据元素在物理位置上 相邻。
3.线性表的链式存储结构主要包括 、 和 三种形式,其中最基本的形式是 。
4.从结构上来看,循环单链表与非循环单链表的不同在于 。
5.一元多项式f(x)=9x13-4x8+3x-5的线性链表表示是 。
6.栈和队列的逻辑结构都是 结构。
7.栈是一种特殊的线性表,其特殊性是 。
8.队列是一种特殊的线性表,其特殊性是 。
9.栈的插入与删除操作都是在 位置进行的;而队列的插入在 进行,删除操作在 进行。
选择题10.中缀形式的算术表达式A+(B-C/D)*E的后缀形式是 。
11.若线性表采用顺序存储结构,每个元素占用4个存储单元,第一个元素的存储地址为100,则第12个元素的存储地址是 。
A.112B.144C.148D.41212.若频繁地对线性表进行插入和删除操作,该线性表应该采用 存储结构。
A.散列B.顺序C.链式D.索引13.若长度为n的非空线性表采用顺序储存结构,删除表中第i个数据元素是,需要移动表中 个数据元素。
A.n+iB.n-iC.n-i+1D.n-i-114.若长度为n的线性表采用顺序储存结构,在表的第i个位置插入一个数据元素,需要移动表中 个数据元素。
A.n+iB.n-iC.n-i+1D.n-i-115.若长度为n的线性表采用顺序储存结构,在表的第i个位置插入一个数据元素的算法的使劲复杂性是 。
A.O(n)B. O(n2)C. O(nlog2n)D. O(log2n)16.线性链表中各结点的地址 。
A.必须连续B.一定不连续C.部分地址必须连续D.可能连续也可能不连续17.在一个具有n个结点的线性链表中查找一个结点,若查找成功,需要平均比较( )个结点。
《数据结构及其应用》笔记含答案 第三章_栈和队列

第3章栈和队列一、填空题1、栈是限定仅在表尾进行插入或删除操作的线性表。
2、栈的修改是按照后进先出的原则进行的。
3、队是一种先进先出的线性表。
4、把队列头尾相接的顺序存储结构称为循环队列。
5、队列也是一种操作受限的线性表,允许插入的一端叫做__队尾___,允许删除的一端叫做__队头__。
二、判断题1、栈和队列的存储,既可以采用顺序存储结构,又可以采用链式存储结构。
(√)2、任何一个递归过程都可以转换成非递归过程。
(√)3、若输入序列为1,2,3,4,5,6,则通过一个栈可以输出序列3,2,5,6,4,1。
(√)4、通常使用队列来处理函数的调用。
(╳)5、循环队列通常用指针来实现队列的头尾相接。
(╳)三、单项选择题1、若让元素1,2,3,4,5依次进栈,则出栈次序不可能出现在(C)种情况。
A.5,4,3,2,1 B.2,1,5,4,3 C.4,3,1,2,5 D.2,3,5,4,1解释:栈是后进先出的线性表,不难发现C选项中元素1比元素2先出栈,违背了栈的后进先出原则,所以不可能出现C选项所示的情况。
2、若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为(C)。
A.i B.n-i C.n-i+1 D.不确定解释:栈是后进先出的线性表,一个栈的入栈序列是1,2,3,…,n,而输出序列的第一个元素为n,说明1,2,3,…,n一次性全部进栈,再进行输出,所以p1=n,p2=n-1,…,pi=n-i+1。
3、数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为(D)。
A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n解释:对于非循环队列,尾指针和头指针的差值便是队列的长度,而对于循环队列,差值可能为负数,所以需要将差值加上MAXSIZE(本题为n),然后与MAXSIZE(本题为n)求余,即(n+r-f)%n。
数据结构-第3章-队列

a
front
b
c
d
e
f
g
rear
3.2 队列的顺序存储及实现
在使用队列前,先初始化队列,此时,队列为空,队头指针 front和 队尾指针rear都指向队列的第一个位置,即front=rear=0,如图3.3 所示。
下标 0 1 2 3 4 5 6Байду номын сангаас7 8 9
3.3 队列的链式存储及实现
(2)判断队列是否为空。 int QueueEmpty(LinkQueue *Q) {
return Q->rear==Q->front;
}
//头尾指针相等队列为空
3.3 队列的链式存储及实现
(3)将元素x入队。先为新结点申请一个空间,然后将x赋给数据 域,并使原队尾元素结点的指针域指向新结点,队尾指针指向新结点, 从而将结点加入队列中。操作过程如图3.20所示。
3.2 队列的顺序存储及实现
(4)入队
int EnQueue(CirQueue *Q , DataType x)
{ if(QueueFull(Q)) printf(“Queue overflow”); else{ Q->data[Q->rear]=x; Q->rear=(Q->rear+1)%QueueSize; } }
3.3 队列的链式存储及实现
链式队列的类型描述如下:
/*结点类型定义*/
typedef struct QNode { DataType data; struct QNode * next; } QueueNode; /*队列类型定义*/ typedef struct { QueueNode * front; //队头指针
第3章线性表的链式存储

(a) 空循环链表
L
a1
a2
...
an
(b) 非空循环链表
3.1.3 双向链表
在单链表结点中只有一个指向其后继结点的next 指针域,而找其前驱则只能从该链表的头指针开始,顺 着各结点的next指针域进行查找,也就是说找后继的时 间复杂度是O(1),找前驱的时间复杂度是O(n)。如果也 希望找前驱像后继那样快,则只能付出空间的代价:每 个结点再加一个指向前驱的指针域prior,结点的结构修 改为下图,这样链表中有两个方向不同的链,用这种结 点组成的链表称为双向链表。
1.带头结点的单链表 2.不带头结点的单链表
3.3.3 单链表插入操作的实现
单链表的插入操作是指在表的第i个位置结点处插入 一个值为data的新结点。插入操作需要从单链表的第一个结 点开始遍历,直到找到第i个位置的结点。插入操作分为在 结点之前插入的前插操作和在结点之后插入的后插操作。
1.前插操作 2.后插操作
2.整数型单链表算法
3.不带头结点的单链表算法
3.2.2 尾插法单链表的创建实现
用头插法实现单链表的创建,比较简单,但读入的 数据元素的顺序与生成的链表中元素的顺序是相反的。若希 望两者次序一致,则用尾插法创建单链表。为了快速找到新 结点插入到链表的尾部位置,所以需加入一个尾指针r用来 始终指向链表中的尾结点。初始状态:头指针L和尾指针r均 为空,把各数据元素按顺序依次读入,申请结点,将新结点 插入到r所指结点的后面,然后r指向新结点,直到读入结束 标志为止。
3.2.2 尾插法单链表的创建实现
L
插入P前的尾指针 插入P后的尾指针
r
3
4
P1
x^
2
3.3 单链表运算的实现
数据结构c 版第二版课后习题答案
数据结构c 版第二版课后习题答案数据结构是计算机科学中的重要概念,它研究如何组织和存储数据,以便能够高效地进行操作和检索。
C语言是一种广泛应用于软件开发的编程语言,而数据结构C版第二版是一本经典的教材,它介绍了C语言中常用的数据结构和算法。
在学习这本教材时,课后习题是检验自己理解和掌握程度的重要方式。
下面我将为大家提供一些课后习题的答案,希望对大家的学习有所帮助。
1. 第一章:引论习题1:数据结构是什么?它的作用是什么?答案:数据结构是一种组织和存储数据的方式,它可以帮助我们更高效地进行数据操作和检索。
它的作用是提供一种合理的数据组织方式,使得我们可以快速地找到和处理需要的数据。
习题2:请举例说明数据结构的应用场景。
答案:数据结构可以应用于各个领域,比如在图像处理中,我们可以使用二维数组来表示图像的像素点;在网络通信中,我们可以使用链表来存储和管理网络节点之间的连接关系;在数据库中,我们可以使用树结构来组织数据的层次关系等等。
2. 第二章:算法分析习题1:什么是时间复杂度和空间复杂度?它们分别表示什么?答案:时间复杂度是衡量算法执行时间的度量,它表示随着输入规模的增加,算法执行时间的增长趋势。
空间复杂度是衡量算法所需内存空间的度量,它表示随着输入规模的增加,算法所需内存空间的增长趋势。
习题2:请解释最坏情况时间复杂度和平均情况时间复杂度的区别。
答案:最坏情况时间复杂度是指在最不利的情况下,算法执行的时间复杂度。
平均情况时间复杂度是指在所有可能输入情况下,算法执行的平均时间复杂度。
最坏情况时间复杂度是对算法性能的保证,而平均情况时间复杂度更能反映算法的平均性能。
3. 第三章:线性表习题1:请实现一个线性表的顺序存储结构。
答案:可以使用数组来实现线性表的顺序存储结构。
定义一个固定大小的数组,然后使用一个变量来记录线性表中元素的个数,通过数组下标来访问和操作元素。
习题2:请实现一个线性表的链式存储结构。
线性表的链式存储结构实验报告
实验一:线性表的链式存储结构【问题描述】某项比赛中,评委们给某参赛者的评分信息存储在一个带头结点的单向链表中,编写程序:(1)显示在评分中给出最高分和最低分的评委的有关信息(姓名、年龄、所给分数等)。
(2)在链表中删除一个最高分和一个最低分的结点。
(3)计算该参赛者去掉一个最高分和一个最低分后的平均成绩。
【基本要求】(1)建立一个评委打分的单向链表;(2)显示删除相关结点后的链表信息。
(3)显示要求的结果。
【实验步骤;】(1)运行PC中的Microsoft Visual C++ 6.0程序,(2)点击“文件”→“新建”→对话窗口中“文件”→“c++ Source File”→在“文件名”中输入“X1.cpp”→在“位置”中选择储存路径为“桌面”→“确定”,(3)输入程序代码,程序代码如下:head=create(PWRS);printf("所有评委打分信息如下:\n");print(head);//显示当前评委打分calc(head);//计算成绩printf("该选手去掉 1 最高分和 1 最低分后的有效评委成绩:\n");print(head);//显示去掉极限分后的评委打分}void input(NODE *s) #include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <iostream.h>#include <conio.h>#define NULL 0#define PWRS 5 //定义评委人数struct pw //定义评委信息{ char name[6];float score;int age;};typedef struct pw PW;struct node //定义链表结点{struct pw data;struct node * next;};typedef struct node NODE;//自定义函数的声明NODE *create(int m); //创建单链表int calc(NODE *h); //计算、数据处理void print(NODE *h); //输出所有评委打分数据void input(NODE *s);//输入评委打分数据void output(NODE *s);//输出评委打分数据void main(){NODE *head;float ave=0;float sum=0;{printf("请输入评委的姓名: ");scanf("%S",&s->);printf("年龄: ");scanf("%d",&s->data.age);printf("打分: ");scanf("%f",&s->data.score);printf("\n");}void output(NODE *s){printf("评委姓名: %8s ,年龄: %d,打分: %2.2f\n",s->,s->data.age,s->data.score);}NODE *create(int m){NODE *head,*p,*q;int i;p=(NODE*)malloc(sizeof(NODE));head=p;q=p;p->next=NULL;for(i=1;i<=m;i++){p=(NODE*)malloc(sizeof(NODE));input(p);p->next=NULL;q->next=p;q=p;}return (head);}void print(NODE *h){ for(int i=1;((i<=PWRS)&&(h->next!=NULL));i++){h=h->next;output(h); }printf("\n");}int calc(NODE *h){NODE *q,*p,*pmin,*pmax;float sum=0;float ave=0;p=h->next; //指向首元结点pmin=pmax=p; //设置初始值sum+=p->data.score;p=p->next;for(;p!=NULL;p=p->next){if(p->data.score>pmax->data.score) pmax=p;if(p->data.score<pmin->data.score) pmin=p;sum+=p->data.score;}cout<<"给出最高分的评委姓名:"<<pmax-><<"年龄: "<<pmax->data.age<<"分值:"<<pmax->data.score<<endl;cout<<"给出最低分的评委姓名:"<<pmin-><<"年龄: "<<pmin->data.age<<"分值:"<<pmin->data.score<<endl;printf("\n");sum-=pmin->data.score;sum-=pmax->data.score;for (q=h,p=h->next;p!=NULL;q=p,p=p->next){if(p==pmin){q->next=p->next; p=q;}//删除最低分结点if(p==pmax) {q->next=p->next; p=q;}//删除最高分结点}ave=sum/(PWRS-2);cout<<"该选手的最后得分是:"<<ave<<endl;return 1;}实验结束。
数据结构C语言版部分习题及答案[2]
第二章习题与解答一判断题1.线性表的逻辑顺序与存储顺序总是一致的。
2.顺序存储的线性表可以按序号随机存取。
3.顺序表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。
4.线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此是属于同一数据对象。
5.在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。
6.在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。
7.线性表的链式存储结构优于顺序存储结构。
8.在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。
9.线性表的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。
10.在单链表中,要取得某个元素,只要知道该元素的指针即可,因此,单链表是随机存取的存储结构。
二单选题 (请从下列A,B,C,D选项中选择一项)1.线性表是( ) 。
(A) 一个有限序列,可以为空;(B) 一个有限序列,不能为空;(C) 一个无限序列,可以为空;(D) 一个无序序列,不能为空。
2.对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。
插入一个元素时平均要移动表中的()个元素。
(A) n/2 (B) n+1/2 (C) n -1/2 (D) n3.线性表采用链式存储时,其地址( ) 。
(A) 必须是连续的;(B) 部分地址必须是连续的;(C) 一定是不连续的;(D) 连续与否均可以。
4.用链表表示线性表的优点是()。
(A)便于随机存取(B)花费的存储空间较顺序存储少(C)便于插入和删除(D)数据元素的物理顺序与逻辑顺序相同5.某链表中最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用( )存储方式最节省运算时间。
(A)单链表(B)双链表(C)单循环链表(D)带头结点的双循环链表6.循环链表的主要优点是( )。
(A)不在需要头指针了(B)已知某个结点的位置后,能够容易找到他的直接前趋(C)在进行插入、删除运算时,能更好的保证链表不断开(D)从表中的任意结点出发都能扫描到整个链表7.下面关于线性表的叙述错误的是( )。
第3章 线性表及其存储结构
链式存储结构,既可用来表示线性结构, 也可用来表示非线性结构。线性表的链式存 储结构,称为线性链表。 对线性链表而言,它不要求逻辑上相邻的 元素在物理位置上也相邻。其存储单元既可 以是连续的,也可以是不连续的,甚至可以 零散分布在内存中的任何位置上。 通常,为了适应线性链表的存储,计算机 的存储空间被划分成一个一个的小块,每一 小块占若干字节,这些小块就是存储结点。 存储结点的结构,如图 3-2 所示。
在稍微复杂的线性表中,一个数据元素还 可以由若干个数据项组成。例如,某班的学 生情况登记表是一个复杂的线性表,表中每 一个学生的情况就组成了线性表中的每一个 元素,每一个数据元素包括学号、姓名、性 别、入学成绩4个数据项。
3.2线性表的顺序存储及其运算
3.2.1 线性表的顺序存储 线性表的顺序存储结构称为顺序表。
第3章 线性表及其存储结构
3.1线性表的基本 概念 3.2线性表的顺序 存储及运算 3.3线性表的链式 存储及运算
3.1 线性表的基本概念
线性表是由 n (n≥0)个数据元素 a1 ,a2 ,…,an 组成的一个有限序列。表中的每一个数据元 素,除了第一个外,有且只有一个前件;除 了最后一个外,有且只有一个后件。即线性 表或是一个空表或可以表示为:
(a1 ,a2 ,…,ai ,…,an)其中 ai(i=1,2,…,n) 是属于数据对象的元素,通常也称其为线性 表中的一个结点。
数据元素在线性表中的位置,只取决于它们 自己的序号 。 非空线性表的结构特征为: ① 有且只有一个根结点a1 ,它无前件;
② 有且只有一个终端结点an ,它无后件;
③ 除根结点与终端结点外,其他所有结点 有且只有一个前件,也有且只有一个后件。线 性表中结点的个数n称为线性表的长度。当 n=0时,称为空表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.2 基于单链表的算法实现
【例3-3】:以“饮食中心快餐配送餐管理”任务为例, 采用带头结点的动态链表设计数据结构。 单链表类型定义: (1).定义元素数据类型 typedef struct { char number[7]; /*序号*/ char name[10]; /*姓名*/ char time[10];/*时间*/ int amount;/*人数*/ } ElemType; (2). 定义链表及结点类型 typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
任务2:静态链表存储结构举例并采用C语言定义
3.1.4 动态链表的实现
使用链表的原因: 使用链表的原因: 第一, 第一,如果系统不能提供足 够大的地址连续的内存空 间时,可以考虑使用链表; 间时,可以考虑使用链表; 第二, 第二,需要对线性表频繁地 进行插入和删除操作时, 进行插入和删除操作时, 也考虑使用链表。 也考虑使用链表。 动态链表结点定义一般形式: typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
第3章 线性表的链式存储
主要知识点: 主要知识点: ● 线性表的链式存储结构。 ● 链表中有关概念的含义,如头结点、头 指针,首元结点、尾元结点的区别,以及 循环链表、双向链表的区别等。 ● 各种链表上实现线性表各种操作的方法 即有关算法的设计。 ● 建立利用数据结构知识进行程序设计的 思考方式。
教学重点与难点 重点:顺序表单链表结构的各种基本算法,以 及相关的时间性能分析。 难点:设计链表结构算法解决线性表相关实际 问题。 思考问题: 思考问题: 1、线性表链式结构特点 2、如何利用线性表链式结构的知识解决实际问 题,确定线性表链式结构的应用题目。
3.C语言描述说明 (1).LinkList和LNode * 是不同名字的同一个指针类型(命名的不同是为了概念 上更明确)。 (2).LinkList类型的指针变量head表示它是单链表的头指针。 (3).LNode *类型的指针变量p表示它是指向某一结点的指针。 为了便于描述,下面给出有关链表的术语。在一个链表中称表头结点指针为 头指针,如图 3.5 Head指针变量。由于从头指针出发可以搜索到链表中各结点, 头指针 因而常用头指针作为链表的名称,如图 3.5快餐配送信息链表为Head。 4.定义链表变量两种定义形式: (1)LinkList Head; (2)LNode *Head;
3.1.2 单链表的数据定义
结点结构:
数据域
指针域
数据域:存放结点数据信息值,例如订餐顾客数据信息。 指针域:存放结点的直接后继的地址(位置)。 注意: 注意: (1)、链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。 (2)、每个结点只有一个链域的链表称为单链表(Single Linked List)。
3.2 基于单链表的算法实现
3.2.1 单链表的基本算法实现
1.构造一个空表 /*构造一个空表 构造一个空表* int Init_LinkList(LinkList *Head_pointer) /*构造一个空表*/ { LinkList p; /*分配一个结点 分配一个结点* p=(LinkList)malloc(sizeof(LNode)); /*分配一个结点*/ if (p==NULL) /*分配失败 分配失败* return OverFlow; /*分配失败*/ /*头指针指向新结点 头指针指向新结点* *Head_pointer=p; /*头指针指向新结点*/ /*构造成功 构造成功, return OK; /*构造成功,返回 */ }
头结点及作用: 头结点是在链表的开始结点之前附加一个结点。它具有两个优点: (1).由于开始结点的位置被存放在头结点的指针域中,所以 在链表的第一个位置上的操作就和在表的其它位置上操作一 致,无须进行特殊处理; (2).无论链表是否为空,其头指针都是指向头结点的非空指 针(空表中头结点的指针域空),因此空表和非空表的处理 也就统一了。 注意: 注意: 头结点数据域的阴影表示该部分不存储信息。在有的应用中 可用于存放表长等附加信息
3.1.4 动态链表的实现
例3-2:饮食中心快餐配送餐管理动态链表存储结构设计 1.存储结构分析: 而在C语言程序设计中,可以用malloc函数申请动态变量(存储空间),用 free释放变放 的。 2.订餐顾客信息的动态链类型:
(1).定义元素数据类型 ) 定义元素数据类型 typedef struct { char number[7]; /*序号 序号*/ 序号 char name[10]; /*姓名 姓名*/ 姓名 char time[10];/*时间 时间*/ 时间 int amount;/*人数 人数*/ 人数 } ElemType;
课程任务:线性表链式结构案例理解,完成课程任务设计。 课程任务:线性表链式结构案例理解,完成课程任务设计。 1、考核方式:课程报告和程序设计 、考核方式: 2、作业题目:依据选定的线性表结构实用案例题目,设计完 、作业题目:依据选定的线性表结构实用案例题目, 成课程任务。例如: 饮食中心订餐管理系统 系统” 成课程任务。例如:课程任务实例 “饮食中心订餐管理系统”。 3、作业要求:分析案例实现方法,结合案例设计自己的作业 、作业要求:分析案例实现方法, 任务。 任务。
3.1 线性表的链式存储结构
3.1.1 为什么要使用链式存储结构
【案例】:饮食中心快餐配送餐管理 。 案例】
图 3.1 快餐配送信息
3.1 线性表的链式存储结构
需求分析: 需求分析: 1、不需要事先准备一张足够大的纸; 、不需要事先准备一张足够大的纸; 2、每张小纸条写完以后,把这张纸条排列到正确 、每张小纸条写完以后, 位置时,不会影响到其他的纸条; 位置时,不会影响到其他的纸条; 3、订餐顾客用完餐后,把记录该顾客信息的纸条 、订餐顾客用完餐后, 抽出来销毁(或存档)。 抽出来销毁(或存档) 4、数据元素之间的逻辑关系为线性关系。 、数据元素之间的逻辑关系为线性关系。 问题思考: 、预定顺序如采用顺序表物理存储结构存在的问题。 问题思考:1、预定顺序如采用顺序表物理存储结构存在的问题。 2、考虑采用链式物理存储结构的解决。 、考虑采用链式物理存储结构的解决。
例3-1:饮食中心快餐配送餐管理静态链表存储结构设计 (1)存储结构分析
(2)存储结构C语言定义如下: 定义顾客信息数据类型: typedef struct { char name[10]; /*姓名*/ char time[10]; /*时间*/ int amount; /*份数*/ char adress[17]; /*地址*/ } ElemType; 定义结点类型: typedef struct node { ElemType data; /*数据域 */ Int next; /*指针域 */ } SLNode; 定义静态单链表: SLNode letter[100]
3.1.2
单链表的数据定义
链表的存储特点(参见图3.2): 1、 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以 是连续的,也可以是不连续的),例如三个订餐顾客的订餐数据信息的 存储空间是可以定义在任意的存储区域。 2、链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点 间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点 的地址(或位置)信息(如图3.2B),三个订餐顾客的订餐数据的逻辑 次序与物理存储次序不相同。
typedef struct node data; { ElemType data; /*数据域 /*数据域 */ struct node *next; *next; /*指针域 /*指针域 */ LNode, LinkList; } LNode,*LinkList;
(2). 定义链表及结点类型 typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
问题思考: 问题思考:总结链式存储结构的特点
单链表定义的一般形式: 由分别表示a1,a2,…,an, 的n 个结点依次相链构成的链表,称为线性表的链 式存储表示,由于此类链表的每个结点中只包含一个指针域,故称为单链 表或线性链表。 任务1: 任务 :举例说明为什么要使用链式存储结构。
3.1.3静态链的实现 静态链的实现 静态链表特点: ● 用数组来存储元素的值和地址。 ● 程序运算过程中,数组元素的个数固定不变。
子函数参数说明: 子函数参数说明:
typedef struct node { ElemType data; /*数据域 */ 数据域 struct node *next; /*指针域 */ 指针域 } LNode,*LinkList ,
int InsertL_i(LinkList Head, ElemType x,int i) /*在第 个结点后面插入 在第i个结点后面插入 在第 个结点后面插入*/ { LNode *p,*q;int k=0; p=( LinkList)malloc(sizeof(Node)); /*分配一个结点 分配一个结点*/ 分配一个结点 if (p==NULL) return OverFlow; /*分配失败 分配失败*/ 分配失败 /*数据域赋值 数据域赋值*/ 数据域赋值 strcpy(p->data.number,x.number);/*输入序号 输入序号*/ 输入序号 strcpy(p->,);/*输入姓名 输入姓名*/ 输入姓名 strcpy(p->data.time,x.time);/*输入时间 输入时间*/ 输入时间 p->data.amount=x.amount;/*输入人数 输入人数*/ 输入人数 q=Head; while(q!=NULL && k!=i-1) /*q指向第一个元素 指向第一个元素*/ 指向第一个元素 { q=q->next;k++; /*q取后继元素的指针 取后继元素的指针*/ 取后继元素的指针 } if (q==NULL) printf(“序号错 序号错/n”); 序号错 else { p->next=q->next; /*设置新结点的指针指向第 个结点的后继结点 设置新结点的指针指向第i个结点的后继结点 设置新结点的指针指向第 个结点的后继结点*/ q->next=p; /*设置第 个结点的指针域指向新结点 设置第i个结点的指针域指向新结点 设置第 个结点的指针域指向新结点*/ return OK; /*插入成功,返回 */ 插入成功, 插入成功 } return Error; /*插入未成功 插入未成功*/ 插入未成功 }