ImageVerifierCode 换一换
格式:DOCX , 页数:27 ,大小:588.01KB ,
资源ID:9017819      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9017819.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(严蔚敏数据结构讲义第02章 线性表.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

严蔚敏数据结构讲义第02章 线性表.docx

1、严蔚敏数据结构讲义第02章 线性表第02章 线性表本章知识结构:线性表的特点:1. 有唯一的头;2. 唯一的尾;3. 除头外都有一个直接前驱;4. 除尾外都有一个直接后继。2.1 线性表的类型定义一、 线性表是n(n=0)个数据元素的有限序列有限个元素;元素之间有次序。长度:表中元素的个数。存储容量:整个线性表所占的空间。位序:元素所在位置的序号,即第几个。线性表的基本操作:1.访问(元素查询,定位);2.插入元素;3.删除元素。线性表的抽象数据类型定义(三元法定义)ADT List数据对象;数据关系;基本操作2.2 顺序表(sequence)线性表的顺序表示与实现一、 特点:1. 逻辑地址相

2、邻,物理地址也相邻;2. 优点:可随机访问;缺点:插入、删除不方便。二、 实现:一维数组三、 C语言知识复习(一) typedef int DataType;给整型int定义一个别名DataType,之后就可以使用DataType定义整型变量了,例如: DataType x,y=8;(二) 结构体类型的定义struct cardint num; char name20; 定义了一个结构体card(三) 结构体变量的定义struct card stu1,stu2;其中struct card是一个整体,表示结构体类型名(四) 给结构体类型名定义别名typedef struct card DataT

3、ype;给结构体struct card定义一个别名DataType (五) 给匿名结构体定义别名typedef structint month; int day; int year; Date; /该结构体为匿名结构体,相当于类的匿名对象。即该结构体无名称,只有别名class PC; new PC().action(); /匿名对象的使用(六) sizeof函数:返回一个对象或者类型所占的内存字节数。如:sizeof(int)2(七) 用typedef定义指针型别名typedef char *String; /声明String为字符指针类型typedef struct node *LinkLi

4、st; /声明LinkList为struct node类型的指针(八) malloc函数和free函数 memory allocation内存分配1. 函数原型及说明:void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。关于分配失败的原因,应该有多种,比如说空间不足就是一种。void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。2. 函数的使用: char *Ptr = NULL;

5、 Ptr = (char *)malloc(100 * sizeof(char); /malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换(九) calloc函数功能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。 跟malloc的区别: calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。(一十) realloc函数原型:extern void *realloc(void *mem_addr

6、ess, unsigned int newsize); 语法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。 头文件:#include 有些编译器需要#include ,在TC2.0中可用alloc.h头文件 功能:先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。 返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 注意:这里原始内存中的数据还是保持不变的。当内存不再使用时,应使用free()函数将内

7、存块释放。四、 线性表的结构定义存储结构typedef struct ElemTpye *elem; /存储空间首地址 int length; /存储长度 int ListSize; /存储容量五、 线性表的插入1.检查i值是否超出所允许的范围(1in+1),若超出,则进行“超出范围”错误处理; 2.检查容量是否已满,若已满则需扩充存储容量;3.将线性表的第i个元素和它后面的所有元素均向后移动一个位置; 4.将新元素写入到空出的第i个位置上; 5.使线性表的长度增1。六、 顺序表的删除七、 顺序表的查找八、 线性表合并九、 顺序存储优缺点2.3 链表线性表的链式表示与实现一、线性链表/单链表(

8、一)结点结构定义(二)基本运算 1.建单链表 (1)头插法建单链表 ListLink HeadInsertCreateList() /头插法创建单链表 ListLink head,s; char ch; head=NULL; printf(Please input character(#-stop).n); ch=getchar(); while(ch!=#) s =(ListLink)malloc(sizeof(ListNode); /申请空间 s-data = ch; /结点数据域赋值 s-next = head; /将新节点的指针域指向头指针(即指向第一个数据元素地址) head = s

9、; /将头指针指向新结点 ch = getchar(); /继续接收键盘字符,循环创建数据元素 return head; (2)尾插法建单链表 ListLink TailInsertCreateList() /尾插法创建单链表 ListLink head,tail,s; /head头指针;tail尾指针;s临时指针 char ch; head = NULL; tail = head; /起始时,单链表无数据元素,头指针和尾指针都为空 printf(Please input character(#-stop).n); ch=getchar(); while(ch!=#) s =(ListLink

10、)malloc(sizeof(ListNode); /申请空间 s-data = ch; /结点数据域赋值 s-next = NULL; /新结点作为最后一个结点出现,所以将新结点的指针域置空 if(tail=NULL) /尾结点为空,此时插入第一个元素,应将头指针指向之,之后头指针保持不变 head = s; tail = s; /第一个元素进入,尾指针也要指向第一个元素 else tail-next = s; /第个及以后的元素插入都是直接将元素链入尾部 tail = s; /将尾指针指向新结点 ch = getchar(); /继续接收键盘字符,循环创建数据元素 return head;

11、 2.查找 (1)按值查找linklist *LOCATE(linklist *head,datatype key) linklist *p; phead-next; /头结点不属于表 while(p!=NULL) if (p-data!=key) pp-next; else break; return p; (2)按位置(序号)查找可拓展到遍历linklist *GET(linklist *head,int i) int j; linklist *p; phead;j0; while(p-next!=NULL)&(jnext; j+; if (i=j) return p; else retu

12、rn NULL; 3.插入元素 (1)单个结点后插操作/后插元素,L为单链表头指针,在q所指向的元素后面插入一个元素,值为eListLink ListInsertAfter(ListLink L, ListLink p, DataType e) ListLink q = (ListLink)malloc(sizeof(ListNode); if(q=NULL) printf(Memory allocation Error.n); exit(0); q-data = e; q-next = p-next; p-next = q; return L; (2)单个结点前插操作InsertBefore

13、(linklist *head,linklist *p,datatype x) linklist *s,*q; smalloc(sizeof(linklist); s-datax; qhead; while(q-next!=p) qq-next; s-nextp;q-nexts; 4.删除元素 (1)删除后继结点二、按位置查找(即访问第i个元素)的时间复杂度是;Addi=Add0+(i-1)*d按值查找(即查找值为x的元素),需要比较(n+1)/2次,时间复杂度为;插入元素需要平均移动节点n/2个;设线性表有n个元素,如果要在第1个元素位置插入元素,则需要移动n个元素;如果要在第2个元素位置插

14、入,则需要移动n-1个元素,如果要在第n个元素位置插入需要移动1个;如果要在最末尾插入元素,则不需要移动元素,即移动0个元素,列出所有要移动元素的和,n + (n-1) + (n-2) + + 1 + 0,最终的n(n+1)/2。插入总次数为n+1,所以移动平均数为n(n+1)/2(n+1) = n/2。删除元素的平均时间复杂度为(n-1)/2。链式存储:查找(访问)第i个元素的时间复杂度是;从第1个找第2个,再通过第2个找第3个,插入元素的平均时间复杂度为;删除元素的平均时间复杂度为。二、 静态链表与动态链表静态链表: 所有结点都是在程序中定义,不是临时开辟的,也不能用完后释放。静态链表中能

15、容纳的元素个数的最大数在表定义时就确定了,以后不能增加。静态链表使用结构体数组来实现线性链表的功能。因为其用游标cur来指示下一个数据元素的存储位置,因此存取数据时静态链表与线性链表(单链表)是相似的。线性链表在存取第i个元素时,是先找到第一个元素,然后根据链接依次找到第2个、第3个,直到找到第i个,所以静态链表在存取表中第i个元素的时间同i有关。动态链表: 在需要时才开辟一个结点的存储单元。无论是静态链表还是动态链表,都是链式存储,所以静态链表和动态链表在元素的插入、删除操作上类似,不需要做元素的移动。三、 线性表查找元素的方法通常有顺序查找和折半查找两种。顺序查找适合于顺序存储和链式存储;

16、折半查找只适合于顺序存储。四、 线性表的头指针、头结点、表头结点表头结点表示线性表中第一个存储数据的结点,即第一个数据元素的结点。线性表有的有头结点,有的没有头结点,头结点是在线性表第一个数据元素结点的前面再加一个结点,该结点同数据结点结构相同,但是不存储数据,只是用来标识线性表的起始位置。如果线性表有头结点,则指向头结点的指针叫头指针;如果线性表没有头结点,则指向表头结点的指针叫头指针。第一章 栈、队列和数组一、用单链表表示栈,总是链表头对应栈的栈顶,链表尾对应栈的栈尾;用单链表表示队列时,用链表头对应队列的队头,链表尾对应队列的队尾。二、 对称矩阵aij进行压缩存储,如果按行存储下三角阵,

17、则LOC(i,j)的存放位置: LOC(i,j) = (ij,即元素位于下三角时)LOC(i,j) = (ij,即元素位于上三角时)三、 使用循环队列来判断一个队列是空是满(队头front,队尾rear,队列最大容量为max): 判断栈满:front = (rear + 1)%max 判断栈空:front = rear 栈空计算队列中元素的个数:(rear front + max) % max四、 后缀表达式前序遍历是前缀式=波兰式中序遍历是中缀式后续遍历是后缀式=逆波兰式第二章 树和二叉树一、 树的基本概念1 结点的度:结点的分支数,即结点分叉的总数(不含父叉)。2 结点的层次(高度):结点

18、处在树的第几层,根结点的层次是1。3 树的度:树中所有结点度的最大值即最茂密的那个结点的分叉数。4 树的深度(高度):树中所有结点层次的最大值树枝的最大深度。二、 二叉树(一)属性1 二叉树第i层上至多有2i-1个结点。2 深度为k的二叉树至多有2k-1个结点,最少有k个结点。3 二叉树叶子结点数总比度为2的结点个数多1。4 二叉树的度最多为2,但不一定为2,有可能为0(只含一个根结点的树),也有可能为1(一个根结点只含左子树,无右子树)。(二)存储结构1顺序存储:将二叉树补成完全二叉树(无结点的地方补0),然后按层次存储。 2链式存储 (1)二叉链表:数据域;左指针指向左子树;右指针指向右子

19、树。方便找子树,不方便找双亲。 (2)三叉链表:数据域;左指针指向左子树;右指针指向右子树;双亲指针指向双亲。(三)二叉树的遍历先序、中序和后序,都是以根结点出现的次序而言的。 先序:先根,再左,再右。前缀(波兰式) 中序:先左,再根,再右。中缀 后序:先左,再右,再根。后缀(逆波兰式)1 一个前序遍历+一个后序遍历不能唯一确定一个二叉树。2 一个中序遍历+一个前序遍历能唯一确定一棵二叉树;一个中序遍历+一个后序遍历也能唯一确定一棵二叉树。(即只要是含有中序遍历,即可确定一棵二叉树)。3 无论先序、中序还是后序遍历,二叉树叶子结点的相对排列顺序不变,因为都是先左后右。(四)线索二叉树 Tag为

20、0表示相应的Child指针指向子树结点;如果Tag为1则表示指针指向前驱或后继结点。LChildLTagDataRTagRChild三、 特殊二叉树(满二叉树和完全二叉树)(一) 满二叉树深度为k的满二叉树,第k层的结点数为2k-1,总结点数为2k-1。(二) 完全二叉树定义:(1)叶子结点只能出现在树的最高两层 (2)树的层次排列无间断编号。1 深度为k的完全二叉树最多结点数为2k-1(满二叉树),最少为2k-1(深度为k-1的满二叉树+1)。2 满二叉树为完全二叉树。3 具有n个结点的完全二叉树的深度为+ 1。4 完全二叉树的n0 = n2 + 1。5 完全二叉树的n1 = 0 或 n1

21、= 1。6 完全二叉树的总结点数 n = n0 + n1 + n2 = 2n0 - 1 + n1 =2n1+1+n1(=2n0 或2n0-1;=2n1+1或2n1+2)四、 树和森林(一) 树的存储结构1 双亲表示法:顺序存储,便于查找双亲。2 孩子表示法:顺序 + 链式3 孩子兄弟表示法:二叉链表,左指第一个孩子,右指第一个兄弟。(二) 森林和二叉树的相互转换1 一般树转化为二叉树:将树按孩子兄弟法表示,左子树只保留父亲和长子关系,右子树是年龄最近的两个兄弟的连线。一般树转化为二叉树之后,根结点没有右子树。2 森林转换为二叉树先将森林中的各树转化为二叉树,然后把第1棵树的根结点作为总二叉树的

22、根结点,把第2棵树的根结点作为第1棵树根结点的右子树,把第3棵树的根结点作为第2棵树的右子树(1)森林转换为二叉树,则森林中第1棵树即变成二叉树根结点的左子树;其余树合起来变成二树根结点的右子树;可如此推演,第2棵树是整个二叉树根结点的右子树中的左子树3 二叉树转化为森林将二叉树根结点的右子树的每个分叉的根结点之间的连线都断开,即成森林。(三) 树和森林的遍历1 树的遍历(1) 先根遍历:先访问树的根结点,再依次先根访问树的各子树。树的先根遍历得到的序列与对应的二叉树的先根遍历序列相等。(2) 后根遍历:依次后根遍历各子树,最后访问根结点。树的后根遍历得到的序列与相应的二叉树的中序序列相等。2

23、 森林的遍历(1) 先序遍历:依次从左至右对森林中的每一棵树进行先根遍历。(2) 中序遍历:依次从左至右对森林中的每一棵树进行后根遍历。五、 树的应用(一)二叉排序树:左小右大根中间,二叉排序树的中序遍历序列即是元素的有序序列(自小到大或自大到小) 平均查找长度:ASL= 比如,一个有12个元素的序列,生成二叉树之后,根结点有20=1个元素;第2层,有22-1=2个元素;第3层有23-1=4个元素;在第4层有12-(1+2+4)=5个元素,则其ASL=(1*1+2*2+3*4+4*5)/12=37/12(二)平衡二叉树排序树,是二叉查找树的另一种形式平衡二叉树又被称为AVL树(区别于AVL算法

24、),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 (三)哈夫曼树和哈弗曼编码 1结点之间的路径长度:树上结点之间的分支数目(即从A点到B点,需要走几个树枝)。 2树的路径长度:从树的根结点到每一个终端结点的路径长度之和。 3结点的带权路径长度:从树的根到该终端结点的路径长度与结点上权值的乘积。 4树的带权路径长度:树中所有终端结点的带权路径长度之和。 5哈夫曼树:带权路径长度最小的二叉树称为最优二叉树,即哈夫曼树。 6构造哈夫曼树的步骤:哈夫曼树没有度为1的结点,所以n=2n0-1。 7哈夫曼编码:哈夫曼树上左

25、0右1,从根到结点的树枝对应的0、1所形成的编码。第三章 图一、 图的基本概念(一) 图的定义及术语1 图的定义(1) 图:图是若干顶点和若干边的集合。若只有顶点而无边,则称顶点离散;有边则称顶点关联。(2) 顶点:图中的数据元素。(3) 边:若顶点u和顶点v之间有关联(即有连线),且连线无方向性,则称(u,v)为边。(4) 弧:若顶点u和顶点v之间有关联(即有连线),且连线有方向性,则称或为弧。(5) 弧头:弧指向的顶点(和箭头相类似),也称弧的终端点中,v是弧头。(6) 弧尾:弧起始的顶点,也称弧的初始点中,u是弧尾。(7) 无向图:图中顶点之间的关联无方向性(即顶点之间由边相连)的图。(

26、8) 有向图:图中顶点之间的关联有方向性(即顶点之间由弧相连)的图。(9) 完全图:任意两个顶点之间都有边的无向图()。(10) 有向完全图:任意两个顶点之间都有两条弧相连的有向图()。2 图中边(弧)与图的顶点的关系(1) 无向图中边e和顶点n之间的关系: (2) 有向图中边e和顶点n之间的关系: (3) 稀疏图、稠密图:有很少边或者弧的图()叫稀疏图;反之称为稠密图。3 权:边或者弧上的数称为权,表示从一个顶点到另一个顶点的距离或花费。4 子图:从一个图中选其部分顶点及这些顶点之间的关联(边或弧)组成的新图称为原图的子图。5 度:和顶点v相关联的边或弧的条数,称为顶点v的度,记作:TD(v

27、)。6 有向图中顶点v的度:和顶点v有关联的弧的数量。这些弧包括v指向其他顶点的弧,也包括其他顶点指向v的弧。7 出度OD(v):由顶点v射向其他顶点的弧的总条数。8 入度ID(v):射向v的弧的总条数。9 图中所有顶点度的和与顶点、边、弧的关系:(1) 无向图中所有顶点度的和,是图中所有边的总数的2倍。(因为一个边对应两个度)(2) 有向图中所有顶点度的和,是图中所有弧的总数的2倍。(因为一个弧也对应两个度,一个出度,一个入度,所以对有向图有:所有顶点出度数总和=所有顶点入度数总和=图中弧的总数=(二) 图的连通性1 路径和回路(1) 路径:顶点Vi走到Vj所经历的顶点序列(包括Vi和Vj)

28、。(2) 有向路径:在有向图中顶点Vi走到Vj所经历的顶点序列(包括Vi和Vj)。(3) 简单路径:路径上没有重复顶点的路径。(4) 路径长度:路径中边或者弧的数量即为路径长度。(5) 回路/环路:路径的起始顶点=路径的重点顶点,则称该路径为回路或环路。(6) 简单回路/简单环:除第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路。(7) 非简单回路:除第一个顶点和最后一个顶点之外,其余顶点有重复出现的回路。2 图的连通性(1) 顶点之间连通:若顶点v和u之间有路径(即由v到u可达),则称v和u是连通的。(2) 连通图:图中任何两个顶点之间都连通。n个顶点的无向图,要想达到连通,最少需要n

29、-1条边,此时图为树状结构;n个顶点的有向图,要想达到连通,最少需要 n 条边,此时图为环状结构。(3) 强连通图:有向图的任何两个顶点正向连通,逆向也连通,则称该有向图为强连通图。(4) 连通分量和极大连通子图连通分量:无向图的最大连通子图,可能含有回路“最大”指的是依附于连通分量中顶点的所有边都加上。强连通分量:有向图的极大强连通子图称为其强连通分量。极大连通子图:3 连通图的生成树问题连通图的生成树就是一棵树,是一没有环路的连通图。生成树若有n个顶点,则其边定为n-1个。二、 图的存储及基本操作(一) 邻接矩阵法顺序存储,用n*n的矩阵A来保存图1. 表示方法对无向图:vi,vj之间有边,则aij=aji=1,否则aij=aji=0,为对称矩阵。对有向图:vi向vj有弧,则aij=1,否则aij=0,不一定是对称矩阵,除非两节点之间是双向连通的。对带权图:vi,vj之间有边(弧),则aij=相应的权,否则aij=INFINITY2. 相关求解(1) 判断vi和vj之间是否有边(弧),看aij的值是1还是0。(2) 求无向图顶点vi的度:第i行或第i列元素之和。(3) 求有向图顶点vi的出度:第i行元素之和。求有向图顶点vi

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1