版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、上节回顾 线性表的顺序表表示,其特点是用物理位置上的邻接关系来表示结点间的逻辑关系,这一特点使得顺序表有如下的优缺点。 其优点是: (1)无须为表示结点间的逻辑关系而增加额外的存储空间; (2)可以方便地随机存取表中任一结点。,其缺点是: (1)插入或删除运算不方便,除表尾的位置外,在表的 其它位置上进行插入或删除操作都必须移动大量的结点, 其效率较低。 (2)由于表要求占用连续的存储空间,存储分配只能预先 进行(静态分配)。因此,当表长变化较大时,难以确定 合适的存储规模。若按可能达到的最大长度预先分配表空间, 则可能造成一部分空间长期闲置而得不到充分利用;若事先 对表长估计不足,则插入操作
2、可能使表长超过预先分配的空间 而造成溢出。,链表的分类 从实现的角度看: 动态链表和静态链表 从链接方式的角度看: 单链表、循环链表和双链表,一、单链表,二、结点和单链表的 C 语言描述,三、线性表的操作在单链表中的实现,四、改进的线性链表类型,五、其它形式的链表,2.3 线性表的链式表示和实现,一、单链表,用一组任意的存储单元存储线性表中的数据元素(这组存储单元可以是连续的,也可以是不连续的)。为了表示每个元素ai 与其直接后继元素ai+1 之间的逻辑关系,对元素ai 来说,除了存储元素本身的信息之外,还必须存储指示其后继结点的地址(或位置)信息,这个信息称为指针(pointer)或 链(l
3、ink)。这两部分信息组成数据元素ai 的存储映象,称为结点。,data,next,结点,数据域 指针域,以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点 (表示数据元素 或 数据元素的映象),以“结点的序列”表示线性表(每个结点中只包含一个指针域) 称作单链表 (Single Linked List),以线性表中第一个数据元素 的存储地址作为线性表的地址,称作线性表的头指针。,头结点,头指针,头指针,有时为了操作方便,在第一个结点之前虚加一个“头结点”,以指向头结点的指针为链表的头指针。,空指针,线性表为空表时, 头结点的指针域为空,线性链表 (ZHAO,QIAN,SUN
4、,LI,ZHOU,WU,ZHENG,WANG) 的线性链表存储结构: 存储地址 数据域 指针域 1 LI 43 7 QIAN 13 13 SUN 1 19 WANG NULL 25 WU 37 31 ZHAO 7 37 ZHENG 19 43 ZHOU 25,头指针H,31,线性链表的逻辑状态,ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG,H,用线性链表表示线性表时,数据元素之间的逻辑关系是由结点中的指针来指示的,逻辑上相邻的两元素其物理位置不要求紧邻。通常把链表画成用箭头相连接的结点的序列,结点之间的箭头表示链域中的指针。由此可见,单链表可由头指针唯一确定。,Typ
5、edef struct LNode ElemType data; / 数据域 struct Lnode *next; / 指针域 LNode, *LinkList;,二、结点和单链表的 C 语言描述,LinkList L; / L 为单链表的头指针,(普通结构体变量),(结构体指针变量),ai=p -data; ai+1 =p -next -data,三、单链表常用操作的实现,GetElem(L, i, j = 1; / p指向第一个结点,j为计数器,while (p / 顺指针向后查找,直到 p 指向第 i 个元素或 p 为空,if ( !p | ji ) return ERROR; / 第
6、 i 个元素不存在 e = p-data; / 取得第 i 个元素 return OK;,线性表的操作 ListInsert( j = 0; while (p / i 大于表长或者小于1,s = (LinkList) malloc ( sizeof (LNode); / 生成新结点 s-data = e; s-next = p-next; p-next = s; /插入 return OK;,s,p,C语言中的两个标准函数: malloc和free 假设p和q是linklist型的变量,则 执行p=(linklist)malloc(sizeof(node)的作用是:由系统生成一个node型的结
7、点,同时将该结点的起始位置赋给指针变量p; 执行free(q)的作用是由系统回收一个node型的结点,回收后的结点可以备作再次生成结点时用。,线性表的操作 ListDelete ( p-next = q-next; e = q-data; free(q);,p,q,Status ListDelete_L(LinkList j = 0; while (p-next / 删除位置不合理,q = p-next; p-next = q-next; / 删除并释放结点 e = q-data; free(q); return OK;,操作 ClearList(,算法时间复杂度:,O(ListLength(
8、L),p,如何从线性表得到单链表?,CreateList( L-next = NULL; /先建立一个带头结点的单链表,for (i = n; i 0; -i) p = (LinkList) malloc (sizeof (LNode); scanf( /插入 ,已知线性表LA和LB中的数据元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。 例如,设 LA=(3,5,8,11) i LB=(2,6,8,9,11,15,20) j 则 LC=(2, 3, 5,6,8,8,9,11,11,15,20) k,例 2-3,当线性表以链式存储结构
9、表示时,它的实现方法以及时间复杂度为多少?,void MergeList_L (LinkList / 释放Lb的头结点 / MergeList_L,用上述定义的单链表实现线性表的操作时,存在的问题:,改进链表的设置:,1单链表的表长是一个隐含的值;,1增加“表长”、“表尾指针” 和 “当前位置的指针” 三个数据域;,2在单链表的最后一个元素之后插入元素时, 需遍历整个链表;,3在链表中,元素的“位序”概念淡化,结点的 “位置”概念加强。,2将基本操作中的“位序 i ”改变为“指针 p ”。,四、改进的线性链表类型,typedef struct LNode / 结点类型 ElemType dat
10、a; struct LNode *next; *Link, *Position;,typedef struct / 链表类型 Link head, tail; / 分别指向头结点和最后 一个结点的指针 int len; / 指示链表长度 Link current; / 指向当前被访问的结点的指针, / 初始位置指向头结点 LinkList;,链表的基本操作:,结构初始化和销毁结构,Status InitList( LinkList / 构造一个空的线性链表 L,其头指针、 / 尾指针和当前指针均指向头结点,表长 / 为零。,Status DestroyList( LinkList / 销毁线性
11、链表 L,L不再存在。,O(1),O(n),引用型操作,Status ListEmpty ( LinkList L ); /判表空,int ListLength( LinkList L ); /求表长,Status Prior( LinkList L ); /改变当前指针指向其前驱,Status Next ( LinkList L ); /改变当前指针指向其后继,ElemType GetCurElem ( LinkList L ); /返回当前指针所指数据元素,O(1),O(1),O(n),O(1),O(1),Status LocatePos( LinkList L, int i ); /改变
12、当前指针指向第i个结点,Status LocateElem (LinkList L, ElemType e, Status (*compare)(ElemType, ElemType); /若存在与e 满足函数compare( )判定关系的 /元素,则移动当前指针指向第1个满足条件的 /元素,并返回OK; 否则返回ERROR,Status ListTraverse(LinkList L, Status(*visit)() ); /依次对L的每个元素调用函数visit(),O(n),O(n),O(n),加工型操作,Status ClearList ( LinkList /重置 L 为空表,Sta
13、tus SetCurElem(LinkList /更新当前指针所指数据元素,Status Append ( LinkList /在表尾结点之后链接一串结点,Status InsAfter ( LinkList /将元素 e 插入在当前指针之后,Status DelAfter ( LinkList /删除当前指针之后的结点,O(1),O(n),O(1),O(1),O(1),五、其它形式的链表,最后一个结点的指针域的指针又指回第一个结点的链表。,1. 循环链表,和单链表的差别仅在于,判别链表中最后一个结点的条件不再是“后继是否为空”,而是“后继是否为头结点”,即 P-next= =L,2. 双向链
14、表,链表中的结点有两个指针域,其一指向直接后继,另一指向直接前趋。,typedef struct DuLNode ElemType data; / 数据域 struct DuLNode *prior; / 指向前驱的指针域 struct DuLNode *next; / 指向后继的指针域 DuLNode, *DuLinkList;,用C语言可描述如下:,3.双向循环链表,空表,非空表,结构特性:d-next-prior=d- prior - next=d,双向链表的操作特点:,有些操作如:ListLength、GetElem、和LocateElem等仅需涉及一个方向的指针,所以和单链表相同。,
15、“插入”和“删除”时需要同时修改两个方向上的指针。,s-next = p-next; p-next = s; s-next-prior = s; s-prior = p;,p,s,插入,Status ListInsert_DuL(DuLinkList / p=NULL,即第i个元素不存在 if (!(s=(DuLinkList)malloc(sizeof(DuLNode) return ERROR; / 存储空间分配失败 S-data=e; s- prior = p- prior; p- prior -next = s; s-next= p; p-prior = s; return OK;,删
16、除,q=p -next; p-next = p-next-next; p-next-prior = p; free(q);,p,q,Status ListDelete_DuL(DuLinkList / p=NULL,即第i个元素不存在 e=p-data; p- prior -next = p-next; p-next-prior= p-prior; free(p); Return OK;,4.静态链表,借用一维数组来描述线性链表,称静态链表。这种描述方法便于在不设“指针”类型的高级程序语言中使用链表结构。 其类型说明如下:,#define MAXSIZE 1000 / 链表的最大长度 Type
17、def struct elemtype data; int cur; component, SlinkListMAXSIZE;,静态链表示例,原始状态,插入“SHI”和删除“ZHENG” 之后的状态,静态链表中定位函数LocateElem的实现,int LocateElem_SL(SLinkList S,ElemType e) /在静态单链线性表L中查找第1个值为e的元素。 /若找到,则返回它在L中的位序; 否则返回0。 i=S0.cur; / i 指示表中第一个结点 while (i / LocateElem_SL,链式存储结构的优缺点: 插入和删除运算时,无须移动表中元素的位置,只需修改有
18、关结点的指针内容; 不需要一块连续的存储空间,只要能存放一个数据元素的空闲结点就可以被利用; 表的规模易扩充。 不能随机访问表中元素,访问时间与元素在表中的位置有关;,在实际应用中采用哪一种存储结构更合适? 对这个问题不能一概而论,这涉及到不同实现方法的选择问题。一般而言,对存储结构的选择应从以下几条区别: 应有利于基本运算的实现。因为运算的具体实现以存储结构的确定为前提,存储结构在一定程度上、一定范围内决定了运算的实现是否方便、高效; 应有利于数据的特性。除了数据的逻辑性外,其他的诸如数据规模也应在选择存储结构时加以考虑; 应有利于软件环境。数据的存放方式对存储结构有不同的要求,所以应依据情
19、况适当选择存储结构。具体而言,即应主要从存储空间、运算时间、程序设计语言三方面考虑。即, 存储空间 顺序表的存储空间是静态分配的,在程序执行之前必须明确规定它的存储规模。若线性表的长度n变化较大,则存储规模难于预先确定。估计过大会造成浪费,估计过小又会产生空间溢出。而链式存储结构的存储空间是动态分配,只要内存空间有空间,就可动态申请内存空间,不会产生溢出。 因此,当线性表的长度变化较大,难以估计其存储规模 时,以采用动态链表作为存储结构为好。,对于存储空间的考虑也可以存储密度的大小来衡量。 在链表中的每个结点,除了数据域外,还要额外设置指针 域,从存储密度来讲,是不经济的。 其中 存储密度=(
20、结点数据本身所占用的存储量)/(结点结构所占用的存储总量) 一般地,存储密度越大,存储空间的利用率就越高。 显然,顺序表的存储密度为1,而链式存储结构的存储 密度则小于1。 因此,当线性表的长度变化不大,易于事先确定其大小 时,为了节约存储空间,宜采用顺序表作为存储结构。, 运算时间 顺序存储结构是一种随机存取的结构,便于元素的随机访问。即表中任一元素都可在O(1)时间复杂度情况下迅速而直接地存取。而链式存储结构,必须从头指针开始顺着链扫描才能取得,一般情况下其时间复杂度为O(n),所以对于那些只进行查找运算而很少做插入和删除等的运算,宜采用顺序存储结构。但在顺序表中进行元素的插入和删除运算时
21、,需移动大量元素,平均要移动约半数的元素。尤其是当表中每个元素的信息量较复杂时所花费的时间就更为可观。而采用链式存储结构,由于进行元素的插入或删除,只需修改指针并结合一定的查找。所以,对于那些需要经常频繁地进行元素的插入和删除运算的线性表,其存储结构应采用链式存储结构。, 程序设计语言 对于没有提供指针类型的高级语言,若要采用链表结构,则可以使用游标实现的静态链表。虽然静态链表在存储分配上有不足之处,但它是和动态链表一样,具有插入和删除方便的特点。,总之,线性表的顺序实现和链式实现各有优缺点, 是无法笼统地认定哪种优,哪种劣。只能根据实际 问题的具体实现需要,对各方面的优缺点加以综合 平衡来确
22、定适宜的存储结构。,2.4 一元多项式的表示和相加,在数学上,一元n次多项式 Pn ( x)= p0 + p1 x+ p2 x2 + + pn xn 由n+1个系数唯一确定,可用线性表P来表示 P =(p0 ,p1 , p2 , pn ) 每一项的指数 i 隐含在其系数Pi的序号里。,假设Qm(x)是一元m次多项式,同样可用线性表Q来表示 Q =(q0 ,q1 , q2 , qm ),设mn,则两个多项式相加的结果 Rn ( x)= Pn ( x)+ Qm(x) 可用线性表R表示 R=( p0+q0 , p1+q1, p2+q2 , , pm+qm, pm+1, , pn),在通常应用中,多项
23、式的次数很高且变化很大,使得顺序存储结构的最大长度很难确定,特别是在处理形如 S(x) = 1 + 3x10000 2x20000 的一元稀疏多项式时,就要用一长度为20001的线性表来表示,表中仅有三个非零元素,这种对内存空间的浪费是应该避免的。 如果只存储非零系数项,则显然必须同时存储相应的指数。,一般情况下的一元稀疏多项式可写成 Pn(x) = p1xe1 + p2xe2 + + pmxem 其中:pi 是指数为ei 的项的非零系数, 0 e1 e2 em = n,可用一个长度为m且每个元素有两个数据项(系数项和指数项)的线性表表示: (p1, e1), (p2, e2), , (pm,
24、em) ),P999(x) = 7x3 - 2x12 - 8x999,例如:,可用线性表 ( (7, 3), (-2, 12), (-8, 999) ) 表示,在最坏情况下,n+1(=m)个系数都不为零,则比只存储每项系数的方案要多存储一倍的数据。但对于S(x)类的多项式,这种表示将大大节省空间。,S(x) = 1 + 3x10000 2x20000,对于象 (p1, e1), (p2, e2), (pm, em) 的线性表,有两种存储结构:顺序存储结构和链式存储结构。在实际的应用程序中取用哪一种,则要视多项式作何种运算而定。 若只求多项式的值,运算中无须修改多项式的系数和指数值,采用顺序存储
25、结构为宜。 若求两个多项式之和,采用链式存储结构为宜。,多项式选择顺序存储结构: #define maxlen maxsize; typedef struct / 定义结点类型 float coef; / 系数域 int exp; / 指数域 elemtp; typedef struct elemtp vecmaxlen; / 定义线性表为向量 int len; / 线性表长度 sequenlist; / 类型定义,p1,e1,p2,pm,e2,em,coef exp,多项式选择链式存储结构: typedef struct node / 定义结点类型 float coef; / 系数域 int exp; / 指数域 struct node *next; / 指针域 poly
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 交互式触屏终端产业运行及前景预测报告
- 2025年社区工作人员资格真题库附答案
- CT设备技术升级与维保方案
- 家用自动制面包机产业深度调研及未来发展现状趋势
- 《上帝掷骰子吗:量子物理史话》导读学习通超星期末考试答案章节答案2024年
- 安装工程估价学习通超星期末考试答案章节答案2024年
- 物业管理服务创新考核方案
- 图书馆信息素养提升方案
- 外科器械和设备的储存行业营销策略方案
- 公立学校教师职业道德教育方案
- 2022年江苏省普通高中学业水平测试生物试卷
- 人教版(2024)七年级英语上册教学课件Unit 3 Lesson 6 Reading Plus
- 第4章 跨境电商选品与定价
- 《介绍教室》(教案)-2024-2025学年一年级上册数学北师大版
- 中医科研思路
- 中医创新项目
- 《犯罪心理学(马皑第3版)》章后复习思考题及答案
- 青骄第二课堂2021年禁毒知识答题期末考试答案(初中组)
- 2024-2030年中国射频芯片行业市场发展趋势与前景展望战略分析报告
- 华电线上测评
- 中国吡唑醚菌酯行业市场现状调查及前景战略研判报告
评论
0/150
提交评论