1、,第 1章 数据结构,1.1 基本数据结构与算法 1.2 线性表 1.3 栈和队列 1.4 树和二叉树 1.5 查找 1.6 排序,姓名 学号 成绩 班级李红 9761059 95 机97.6,10,65,865,1.2 线性表,1. 线性表的定义 1) 定义:具有相同数据类型的n(n0)个数据元素组成的有限序列。是最简单、最常用的数据结构。 2) 表示:,L=( a1,a2,a3,ai-1,ai ,ai+1,an ),其中: n为线性表长度(n=0称为空表),表中相邻元素之间存在着顺序关系。a1 :表头元素;an :表尾元素;ai-1称为ai的直接前驱;ai+1 称为ai的直接后继。,1.2
2、.1 线性表的基本概念 (P32),表头,表尾,1.2 线性表,1. 线性表的定义 1) 定义:具有相同数据类型的n(n0)个数据元素组成的有限序列。是最简单、最常用的数据结构。 2) 表示:,L=( a1,a2,a3,ai-1,ai ,ai+1,an ),1.2.1 线性表的基本概念 (P32),3) 线性结构特点:,(1)有且只有一个根结点a1,无前驱 。 (2)有且只有一个终端结点an ,无后继 。 (3)其他结点有且只有一个直接前驱和一个直接后继。,1.2 线性表,1. 线性表的定义 1) 定义:具有相同数据类型的n(n0)个数据元素组成的有限序列。是最简单、最常用的数据结构。 2)
3、表示:,L=( a1,a2,a3,ai-1,ai ,ai+1,an ),1.2.1 线性表的基本概念 (P32),3) 线性结构特点:,4) 线性表的分类(1)简单线性表:数据元素是简单项(数字、字母、季节名等)。 如:(12,34,4,67,8)(2)复杂线性表:数据元素由若干个数据项组成,此时数据元素称为记录或节点, 如学生成绩表.,例2、一副扑克的点数(2,3,4,J,Q,K,A)从以上例子可看出线性表的逻辑特征是: 在非空的线性表,有且仅有一个开始结点a1,它没有直接前趋,而仅有一个直接后继a2; 有且仅有一个终端结点an,它没有直接后继,而仅有一个直接前趋a n-1;,例1、26个英
4、文字母组成的字母表(A,B,C、Z),简单线性表,例3、学生健康情况登记表如下:,复杂线性表,1.顺序表基本概念,1.2.2 线性表的顺序存储结构,1) 顺序存储结构:用一组地址连续的存储空间依次存放线性表的各元素 。,顺序表: 采用顺序存储结构的线性表称为顺序表(一维数组),表中的所有元素所占存储空间连续 表中各元素在存储空间中按逻辑顺序存放,顺序存储结构特点,1.2 线性表,1.顺序表基本概念,1.2.2 线性表的顺序存储结构,1) 顺序存储结构:,2) 第i个元素地址,1.2 线性表,其中: m:每个元素占m个存储单元 Loc(a1)第一个元素地址(基址),对数组而言,b,b+m,b+i
5、*m,b+n*m,存储地址,存储状态,空闲,数据元素在线性表中的位序,1 2,n,i,从存取方式看,线性表的顺序存储结构是可以随机存储的存储结构.,1.顺序表基本概念,1.2.2 线性表的顺序存储结构,1) 顺序存储结构:,2) 第i个元素地址,1.2 线性表,2.顺序表的基本运算 存取: 访问线性表的第i个元素,使用或改变数据元素的值。查找: 在线性表中查找满足某种条件的数据元素。插入: 在线性表的第i个元素之前,插入一个同类型的元素。 (*)删除: 删除线性表中第i个元素。 (*)求表长: 求出线性表中元素的个数。置空表: 建立一个空表。清除表: 将已有线性表变为空表,即删除表中所有元素。
6、,1.顺序表基本概念,1.2.2 线性表的顺序存储结构,1) 顺序存储结构:,2) 第i个元素地址,1.2 线性表,2.顺序表的基本运算,插入和删除,1)顺序表的插入运算: 在线性表的第i个元素之前插入一个新的元素,先移动,后插入。,x,ai,先移动 后插入,x,步骤:,(1)将ai an顺序向后移动,为新元素让出位置 (2)将x置入”空出”的第i个位置,举例:(在第4个和第5个元素之间插入元素91),21,91,插入程序举例(在8个数中任意位置插入一个数): #define N 8 main() int aN+1=12,34,45,6,78,9,10,91, i,j,x;printf(“in
7、put the location to be inserted:”);scanf(“%d,%d”, ,for(j=i-1;j=N-1;j+)aj+1=aj;,for(j=N-1;j=i-1;j-)aj+1=aj;,在第i个位置上作插入x,则需将第i个至第n个元素移动,即共需移动(n-i+1)个元素。,插入运算时间性能分析:,插入运算,时间主要消耗在数据移动上。在长度为n的线性表中插入一个元素,则平均移动元素次数(期望值):,pi:在第i个位置上作插入的概率。,等差数列求和公式: (首项+末项)项数)/2,(n-i+1),线性表(a1,a2,a3)平局移动元素个数: ()*(3+2+1+0)=1
8、.5,在一线性表(a1,a2,a3)中插入任意一数i,求平局移动元素次数:,i 移动次数(n-i+1) 1(插入到第1个数a1前) 3 2 (插入到第2个数a2前) 2 3 (插入到第3个数a3前) 1(插入到第3个数a3后) 0,1.顺序表基本概念,1.2.2 线性表的顺序存储结构,1) 顺序存储结构:,2) 第i个元素地址,1.2 线性表,2.顺序表的基本运算,插入和删除,2)顺序表删除运算:,定义:指将表中第i个元素从线性表中去掉。,原表长为n:( a1,a2,ai-1,ai ,ai+1, an ),新表长为n-1:( a1,a2,ai-1,ai+1, , an ),步骤:,(1)删除a
9、i (2)将ai+1 an, 顺序向前移动 (3)表长减一,举例:(删除第五个元素21),时间性能分析:,时间消耗与插入运算相同,平均移动元素次数:,qi:在第i个位置上作插入的概率。设qi=1/n 共需移动(n-i)个元素。,67,i 移动次数(n-i) 1(删除第1个数a1) 2 2 (删除第2个数a2) 1 3 (删除第3个数a3) 0,线性表(a1,a2,a3)平局移动元素个数: (1/3)*(2+1+0)=1,在一线性表(a1,a2,a3)中插入任意一数i,求平局移动元素次数:,作业:有一数组,存储十个数, 编程序删除其中任意一个数。,1.顺序表基本概念,3.顺序表优点和缺点,优点:
10、,逻辑上相邻元素存储位置也相邻,无需增加额外存储空间可方便随机存取表中任一元素。,缺点:,插入和删除运算不方便,必须移动大量结点,效率较低不适合元素经常变动的大的线性表。,1.2.2 线性表的顺序存储结构,1.2 线性表,2.顺序表的基本运算,链式存储结构特点:,1.2.3 线性表的链式存储结构,存储空间可以不连续。 不要求逻辑上相邻的元素在物理位置上也相邻。 数据元素间逻辑关系由指针域确定。,1.2 线性表,即 链表存储结构是一种动态数据结构,其特点是它包含的据对象的个数及其相互关系可以按需要改变,存储空间是程序根据需要在程序运行过程中向系统申请获得,链表也不要求逻辑上相邻的元素在物理位置上
11、也相邻,它没有顺序存储结构所具有的弱点。,name,sum,next,结构体元素,结构体元素的地址,结构体元素的成员是地址型数据,struct student char name10;int sum;struct student *next;,p,struct student *p;,strcpy(p-name,”zhang”); p-sum=335; p-next=?,head,p1,p2,p3,有四个结构体元素:,head,有四个结构体元素:,head,(3)尾结点的指针域置为“NULL(空)”,作为链表结束的标志,(1)头指针变量head指向链表的首结点。,(2)每个结点由2个域组成:1
12、)数据域存储结点本身的信息。2)指针域指向后继结点的指针。,struct student char name10;int sum;struct student *next;,链式存储结构特点:,2.线性链表: 定义:线性表的链式存储结构称为线性链表,1.2.3 线性表的链式存储结构,数据域: 一部分存放数据元素值 指针域: 存放指针,用于指向该结点的前一个结点或后一个结点,线性链表中 结点组成:,分类:单链表、循环单链表、双向链表,1.2 线性表,其单链表示意图如下:,有一线性表:(bat,cat,eat,fat,hat,jat,lat,mat),110130135160 头指针 head 1
13、65170200205,简化为:,链尾,略,单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名。,例如:若头指针名是head,则把链表称为表head。,head,用C语言描述的单链表如下:,struct node char name20;struct node *next; ; struct node *head;,typedef struct node char name20;struct node *next; LinkList; LinkList *head;,新的类型名代换旧的类型名, 也就是说:LinkList等价与struct node,链式存储结构特点:,2.线性链表:,
14、1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:定义:由n个结点链接,且每个结点中只包含一个指针域的链表。,例:线性单链表( A, B, C, D, E, F ),逻辑状态,其中: head称为单链表的头指针,指向表中的第一个结点,物理状态,头指针 存储地址 数据域 指针域,1 7 13 19 25 31,单链表存取:必须从头指针开始进行,依次顺着指针向链尾方向扫描。找到各个元素,因此说线性表的链式存储结构是一种顺序存储的存储结构。,head,head,head,带头节点的单链表,typedef struct node char data; struct node *next;
15、 Linklist;Linklist *head,*p,*s; char ch;head=(Linklist *)malloc(sizeof(Linklist);printf(“input letters to create a list:n“);while(ch=getchar()!=n)s=(Linklist *)malloc(sizeof(Linklist);s-data=ch;p-next=s;p=s;p-next=NULL;,编程:创建带头节点的单链表。,带头节点的单链表,typedef struct node char data;struct node *next; Linklis
16、t;Linklist *head,*p,*s; char ch;head=(Linklist *)malloc(sizeof(Linklist);printf(“input letters to create a list:n“);p=head;while(ch=getchar()!=n)s=(Linklist *)malloc(sizeof(Linklist);s-data=ch;p-next=s;p=s;p-next=NULL;,2000,B,data,next,struct node char data;struct node *next; Linklist;Linklist *head
17、,*p,*s; char ch;head=(Linklist *)malloc(sizeof(Linklist);printf(“input letters to create a list:n“);p=head;while(ch=getchar()!=n)s=(Linklist *)malloc(sizeof(Linklist);s-data=ch;p-next=s;p=s;p-next=NULL;,A,head,p,用户输入为:ABC,s,p,typedef,struct node char data;struct node *next; Linklist;Linklist *head,*
18、p,*s; char ch;head=(Linklist *)malloc(sizeof(Linklist);printf(“input letters to create a list:n“);p=head;while(ch=getchar()!=n)s=(Linklist *)malloc(sizeof(Linklist);s-data=ch;p-next=s;p=s;p-next=NULL;,A,head,用户输入为:ABC,s,p,s,B,p,typedef,struct node char data;struct node *next; Linklist;Linklist *head
19、,*p,*s; char ch;head=(Linklist *)malloc(sizeof(Linklist);printf(“input letters to create a list:n“);p=head;while(ch=getchar()!=n)s=(Linklist *)malloc(sizeof(Linklist);s-data=ch;p-next=s;p=s;p-next=NULL;,A,head,用户输入为:ABC,s,B,p,s,C,p,NULL,typedef,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:,(1)单
20、链表插入:增加新结点,修改链接指针,后插结点,在指针p所指结点之后插入一个指针s所指的结点 修改p和s所指结点的指针域的指针即可,插入步骤,修改s指针域,使其指向p结点的后继结点:snext=pnext,p,B,X,s,修改p指针域, 使其指向新结点s: pnexts,考虑上述两步骤若颠倒会怎样?,插入步骤,修改s指针域,使其指向p结点的后继结点:snext=pnext,p,B,X,s,修改p指针域, 使其指向新结点s: pnexts,考虑上述两步骤若颠倒会怎样?,后面的结点都将从链表中脱离,它们占用着内存空间,程序却找不到它们了,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存
21、储结构,1.2 线性表,3 .单链表:,(2)单链表删除:不需要移动元素,仅修改指针链接,删除结点,删除p指向的结点 只修改p(被删除结点)的前驱结点的指针域即可,删除步骤,修改q结点指针域 qnextpnext,删除后,q,p,free(p);,先找到p的前驱结点q,qnextqnextnext,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:,1.循环链表,特点:表中最后一个结点的指针域指向头结点,整个链表首尾相连形成一个环。,带头节点的循环链表,优点:从表中任一结点出发均可找到表中其它结点。,对带头结点的单循环链表head为空的判定条件
22、是head-next=head,带头结点的空循环链表,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:,1.循环链表,5.双向链表,定义:在双向链表中,每个结点有两个指针域,next指向后继结点,prior指向前趋结点。,作用:可以方便地沿向前或向后两个方向查找。克服单链表中每个结点只能找到它的后继结点,不能找到前驱结点。若要找前驱结点,必须从头指针开始重新查找的不足。,next,prior,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:,1.循环链表,5.双向链表,(1)插入结点:在p指
23、针所指的结点后插入一个结点q,只需要修改p,q结点的prior和next域即可。,p,c,b,a,x,q,p,p结点作为q结点的前驱:q-prior=p;,p结点的后继作为q结点的后继:q -next=p-next;,q结点作为p 结点的后继结点的前驱结点:p-next-prior=q,q结点作为p结点的后继:p-next=q; (p的后继指向新结点q),确定新结点q的前驱和后继,链式存储结构特点:,2.线性链表:,1.2.3 线性表的链式存储结构,1.2 线性表,3 .单链表:,1.循环链表,5.双向链表,p,(2)删除结点:删除P指针所指结点,只需修改P指针的前驱和后继结点的next,pr
24、ior域即可。,p,p-prior-next = p-next;,p-next-prior= p-prior;,free(p);,c,b,a,习题讲解,1. 线性表的顺序存储结构和线性表的链式存储结构分别是_。A. 顺序存取的存储结构、顺序存取的存储结构 B. 随机存取的存储结构、顺序存取的存储结构 C. 随机存取的存储结构、随机存取的存储结构 D. 任意存取的存储结构、任意存取的存储结构 2. 在单链表中,增加头结点的目的是_。A. 方便运算的实现 B. 使单链表至少有一个结点 C. 标识表结点中首结点的位置 D. 说明单链表是线性表的链式存储实现,BA,3 用链表表示线性表的优点是_。A.
25、 便于插入和删除操作 B. 数据元素的物理顺序与逻辑顺序相同 C. 花费的存储空间较顺序存储少 D. 便于随机存取 1.某线性表采用顺序存储结构,每个元素占4个存储单元,首地址为200,则第12个元素的存储地址是_. A. 248 B. 247 C. 246 D. 244,AD,5. 下列对于线性链表的描述中正确的是_。(05.4月 ) A)存储空间不一定是连续,且各元素的存储顺序是任意的 B)存储空间不一定是连续,且前件元素一定存储在后件元素的前面 C)存储空间必须连续,且前件元素一定存储在后件元素的前面 D)存储空间必须连续,且各元素的存储顺序是任意的,A,填空题数据结构分为逻辑结构和存储
26、结构,循环队列属于 结构。(05.9月),存储结构,练习,带头结点复杂单链表的创建,程序算法: (1)定义三个结构体类型的指针变量head, p, last (2)利用malloc函数开辟头结点,由head, p共同来指向 (3)再利用malloc函数开辟相应的内存空间,由last来指向 (4)由键盘输入数据,赋给last所指向的内存空间 (5)p-next=last; (6)p=last; (7)回到第(3)步;,对带头结点的复杂链表的基本操作创建,Dalas F,Kobe M,Tom M,Yao M NULL,head,程序算法: (1)定义三个结构体类型的指针变量head, p, las
27、t (2)利用malloc函数开辟头结点,由head, p共同来指向 (3)再利用malloc函数开辟相应的内存空间,由last来指向 (4)由键盘输入数据,赋给last所指向的内存空间 (5)p-next=last; (6)p=last; (7)回到第(3)步;,head=p=(strutc stu*) malloc(sizeof(struct stu);,head,p,对带头结点的复杂链表的基本操作创建,程序算法: (1)定义三个结构体类型的指针变量head, p, last (2)利用malloc函数开辟头结点,由head, p共同来指向 (3)再利用malloc函数开辟相应的内存空间,
28、由last来指向 (4)由键盘输入数据,赋给last所指向的内存空间 (5)p-next=last; (6)p=last; (7)回到第(3)步;,Dalas F,head,gets(last-name); scanf(“n%c”, ,p,last,p,对带头结点的复杂链表的基本操作创建,程序算法: (1)定义三个结构体类型的指针变量head, p, last (2)利用malloc函数开辟头结点,由head, p共同来指向 (3)再利用malloc函数开辟相应的内存空间,由last来指向 (4)由键盘输入数据,赋给last所指向的内存空间 (5)p-next=last; (6)p=last;
29、 (7)回到第(3)步;,Dalas F,head,last,p,last,Kobe M,p,对带头结点的复杂链表的基本操作创建,last,程序算法: (1)定义三个结构体类型的指针变量head, p, last (2)利用malloc函数开辟头结点,由head, p共同来指向 (3)再利用malloc函数开辟相应的内存空间,由last来指向 (4)由键盘输入数据,赋给last所指向的内存空间 (5)p-next=last; (6)p=last; (7)回到第(3)步;,Dalas F,head,Kobe M,p,last,end M,如果输入为end,表示数据输入结束,此时,执行p-next=NULL;,已经为链尾,NULL,对带头结点的复杂链表的基本操作创建,struct stu char name30;char sex;struct stu * next; ; struct stu *head, *p, *last;, p=(strutc stu*) malloc(sizeof(struct stu); head=p; last=(strutc stu*) malloc(sizeof(struct stu); gets(last-name);scanf(“n%c”, ,