《线性表(数据结构重难点讲解)》由会员分享,可在线阅读,更多相关《线性表(数据结构重难点讲解)(104页珍藏版)》请在人人文库网上搜索。

1、线性表(数据结构重难点讲解)导读:就爱阅读网友为您分享以下“线性表(数据结构重难点讲解)”资讯,希望对您有所帮助,感谢您对92to.com的支持!第二章 线性表线性结构特点:在数据元素的非空有限集中存在唯一的一个被称作“第一个”的数据元素 存在唯一的一个被称作“最后一个”的数据元素 除第一个外,集合中的每个数据元素均只有一个 前驱 除最后一个外,集合中的每个数据元素均只有一 个后继12.1 线性表的逻辑结构定义:一个线性表是n个数据元素的有限序列如 (a 1 , a 2 ,L L , a i , L L a n)例 英文字母表(A,B,C,.Z)是一个线性表例学号 001 002 姓名 张三 。

2、李四 年龄 18 19 数据元素【注】数据项、记录、文件;2特征:v元素个数n 表长度,n=0 空表 v在一个非空表 (a1,a2,ai,an-1,an) 中的每个数据元素都有一个确定的位置, ai是 第i个数据元素,称i为数据元素ai在线性表中的 位序。 v1in时lai的直接前驱是ai1 ,a1无直接前驱 lai的直接后继是ai1 ,an无直接后继v元素同构,且不能出现缺项3抽象数据类型线性表的定义:ADT List 数据对象: D= ai| aiElemtype,i=1,2,n,n=0 数据关系: R= ai-1,ai| ai-1,aiD,i=2,3,n 基本操作: InitList(&。

3、L) 操作结果:创建一个空的线性表L。 DestroyList(&L) 初始条件:线性表L已存在。 操作结果:销毁线性表。 ClearList(&L) 初始条件:线性表L已存在。 操作结果:将L重置为空表。4ListEmpty(L) 初始条件:线性表L已存在。 操作结果:若L为空表,则返回TRUE,否则返回FALSE。 ListLength(L) 初始条件:线性表L已存在。 操作结果:返回L中数据元素个数。 GetElem(L,i,&e) 初始条件:线性表L已存在,1iListLength(L)。 操作结果:用e返回L中第i个数据元素的值。 LocateElem(L,e,compare( ) 。

4、初始条件:线性表L已存在,compare()是数据元素判定函数。 操作结果:返回L中第1个与e满足关系compare()的数据元素 的位序。若这样的数据元素不存在,则返回值为0。5PriorElem(L,cur_e,&pre_e) 初始条件:线性表L已存在。 操作结果:若cur_e是L的数据元素,且不是第一,则用 pre_e返回它的前驱,否则操作失败,pre_e无定义。 NextElem(L,cur_e,&next_e) 初始条件:线性表L已存在。 操作结果:若cur_e是L的数据元素,且不是最后一个,则 用next_e返回它的后继,否则操作失败, next_e无定义。 ListInsert(。

5、&L,i,e) 初始条件:线性表L已存在,1iListLength(L)+1。 操作结果:在L中第i个位置之前插入新的数据元素e,L 的长度加1。6ListDelete(&L,i,&e) 初始条件:线性表L已存在且非空,1iListLength(L)。 操作结果:删除L的第i个数据元素,并用e返回其值,L的 长度减1。 ListTraverse(L,visit( ) 初始条件:线性表L已存在。 操作结果:依: O( ListLength(La) + ListLength(Lb)152.2 线性表的顺序存储结构顺序表:v定义:用一组地址连续的存储单元依次存放线 性表的数据元素。 v元素地址计算方。

6、法:lLOC(ai)=LOC(a1)+(i-1)*L lLOC(ai+1)=LOC(ai)+Ll其中: uL 一个元素占用的存储单元个数 uLOC(ai) 线性表第i个元素的地址 uLOC(a1) 线性表的第一个数据元素的 存储位置,称为线性表的起始位置或基地址。16v特点:l实现逻辑上相邻物理地址相邻 l实现随机存取 v实现:可用C语言的一维数组实现17存储地址 b b+l内存元素序号 1 2 typedef int ElemType; #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10a1a2b+(i-1)*l b+(n-1)*l b+n。

7、*lai ani ntypedef struct ElemType *elem;/存储空 备 用 空 间间基址int length; /当前长度 int listsize; /当前分配的存储容量b+(maxlen-1)*lSqList;数据元素不是简单类型时,可定义结构体数组18初始化v(生成大小为LISTINITSIZE的线性表)Status InitList_Sq(Sqlist &L) /构造一个空的线性表LL.elem=(ElemType *)malloc(LIST_INIT-SIZE*sizeof(ElemType);If (!L.elem) exit(OVERFLOW); /存储分配。

8、失败;L.length=0;L.listsize=LIST_INIT-SIZE; return OK; / InitList_Sq;/空表长度为0;/ 初始存储容量;19动态申请和释放内存 ( #includestdlib.h )ELEMTYPE *p=(ELEMTYPE *)malloc(M*sizeof(ELEMTYPE); / 分配size字节的存储区,函数返回所分配的内存起始地址,如 内存不足,则返回0;free( p );/ 释放p所指的内存区,无函数返回值; ELEMTYPE *p=(ELEMTYPE *) realloc (ELEMTYPE *p, unsigned size);。

9、 /将p所指的已分配内存区的大小改为size,size可比原来分配的 空间大或小。函数返回指向该内存区的指针。20插入v定义:线性表的插入是指在第i(1i n+1) 个元素之前插入一个新的数据元素x,使长度 为n的线性表变为n+1(a(a11, a 2 ,L L , a i - 1 , a i , L L a n)变成长度为n+1的线性表, a 2 ,L L , a i - 1 , x , a i , L L a n需将第i至第n共(n-i+1)个元素后移21数组下标 0内存 元素序号a1数组下标 0 1内存 元素序号a1 a2 1 21 21a2i-1 iai ai+1i i+1i-1 ix。

10、ai ai+1i i+1n-1 nannn-1 nan-1 annn+1n+122v算法status ListInsert_Sq(SqList &L, int i, ElemType e) /在顺序线性表L中第i个位置之前插入新元素e, / i的合法位置为1=i=ListLength_Sq(L)+1; if (i1|iL.length+1) return ERROR; /i值不合法 if(L.length=L.listsize) /空间不够 newbase=(ElemType * ) realloc ( L.elem,(L.listsize+LISTINCREMENT)*sizeof( Ele。

11、mType ) );if (!newbase) exit(OVERFLOW); / 存储分配失败 L.elem=newbase; / 新基址 L.listsize+=LISTINCREMENT; / 增加存储容量 23q=&L.elemi-1; / q为插入位置,数组下标默认从0开始 for( p=&L.elemL.length-1 ; p=q ; p-) *(p+1)=*p; /插入位置及之后元素右移 *q=e; /插入e +L.length; /表长增加1 return OK; / ListInsert_Sq24v算法时间复杂度T(n)l设Pi是在第i个元素之前插入一个元素的概率, 则在长。

12、度为n的线性表中插入一个元素时,所需 移动的元素次数的平均次数为:Eis =n +1Pi ( n - i + 1 )i =1若认为 Pi = 则 Eis = n 11 n +1n +1+1( n - i + 1) =n 2i =1 T (n ) = O (n )25删除v定义:线性表的删除是指将第i(1i n)个元 素删除,使长度为n的线性表(a(a1, a 2 ,L L , a i - 1 , a i , L L a n)变成长度为n-1的线性表1, a 2 ,L L , a i - 1 , a i + 1 , L L a n需将第i+1至第n共(n-i)个元素前移26数组下标 0 1内存 。

13、元素序号a1 a2 1 2数组下标 0 1内存 元素序号a1 a2 1 2i-1 iai ai+1i i+1i-1 iai+1ai+2i i+1n-1 nann n+1n-2 n-1ann-1n27v 算法Status ListDelete_sq( Sqlist & L, int i, ElemType &e) /在顺序线性表L中删除第i个位置元素e, / i的合法位置为 1= i =Listlength_sq(L); if (i1|iL.length) return ERROR; / I 值不合法 p=&L.elemi-1; /p为被删除的元素位置 e=*p; /被删除元素值赋给e q=&L。

14、.elemL.length-1; /表尾元素位置 for(+p;p=q;+p) *(p-1)=*p; /被删除元素之后的元素右移 - -L.length; /表长减1 return OK; / ListDelete_sq28v算法评价 l设Qi是删除第i个元素的概率,则在长度为n的线 性表中删除一个元素所需移动的元素次数的平均 n 次数为:E de =Q i (n - i)i =1若认为 Q i = 则 E de = 1 n1 n (n - i) = n -1 2ni =1 T (n ) = O (n )故在顺序表中插入或删除一个元素时,平均移 动表的一半元素,当n很大时,效率很低29顺序存储。

15、结构的优缺点v优点 l逻辑相邻,物理相邻 l可随机存取任一元素 l存储空间使用紧凑 v缺点 l插入、删除操作需要移动大量的元素 l预先分配空间需按最大空间分配,利用不 充分 l表容量难以扩充30部分操作在顺序存储结构的线性表中的实 现和时间复杂度的分析求顺序表的表长 L.length,时间复杂度O(1) 取第i个数据元素 L.elemi-1,时间复杂度O(1) 查找函数LocateElem 具体实现,时间复杂度O(L.length)31int LocateElem_Sq(Sqlist L, ElemType e, Status (* compare)(ElemType, ElemType) /。

16、在顺序线性表L中查找第1个值与e满足 compare()的元素的位序 /若找到,则返回其在L中的位序,否则返回0 i=1; / i的初值为第1个元素的位序 p=L.elem; / p的初值为第1个元素的位序 while(i=L.length & !(*compare)(*p+,e) +i; if(i=L.length) return i; else return 0; / LocateElem_Sq32顺序表的合并算法Void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) /已知线性表La和Lb中的数据元素按值非递减排列。 /归并La和Lb得到新。

17、的线性表Lc,Lc的数据元素也按 值非递减排列。 pa=La.elem; pb=Lb.elem; Lc.listsize=Lc.length=La.length+ Lb.length; pc=Lc.elem=(ElemType *) malloc( Lc.listsize* sizeof(ElemType); if(!Lc.elem) exit(OVERFLOW); /存储分配失败 pa_last=La.elem+La.length-1;33pb_last=Lb.elem+Lb.length-1;while(pa=pa_last & pb=pb_last) /归并 if(*pa=*pb) *p。

18、c+=*pa+; else *pc+=*pb+; while(pa=pa_last) *pc+=*pa+; /插入La的剩余元素 while(pb=pb_last) *pc+=*pb+; /插入Lb的剩余元素 /MergeList_Sq34合并算法MergeList_Sq的时间复杂度 O(La.length+ Lb.length) union算法的时间复杂度 O(La.length Lb.length) MergeList_Sq算法做如下改进:添加 当*pa=*pb时,将两者中之一插入Lc中 则算法功能等价于union算法,但时间复杂度不同。 产生不同时间复杂度的原因,见P26 两个因素。35。

19、2.3 线性表的链式存储结构特点:v用一组任意的存储单元存储线性表的数据元素 v利用指针实现了用不相邻的存储单元存放逻辑 上相邻的元素 v每个数据元素ai,除存储本身信息外,还需存 储其直接后继的信息 v结点l数据域:元素本身信息 l指针域:指示直接后继的存储位置结点 数据域 指针域36例 线性表 (ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG)存储地址头指针H 31 1 7 13 19 25 31 37 43数据域LI QIAN SUN*linklist;38Lnode *h, *p; data p next 结点(*p)其中: (*p) 表示p所指向的结点 (*p。

20、).data p-data表示p指向结点的数据域 (*p).next p-next表示p指向结点的指针域 生成一个Lnode型新结点: p=(Lnode *) malloc ( sizeof ( Lnode ) ); 系统回收p结点:free(p)39头结点:在单链表第一个结点前附设一个结点叫头结 点 头CreateList(&L, n) / 生成含 n 个数据元素的链表41线性表的操作 GetElem(L, i, &e) 在单链表中的实现:L 21p18p j 1 3 230p754256 42单链表是一种顺序存取的结构,为找第 i 个 数据元素,必须先找到第 i-1 个数据元素。因此,查找。

21、第 i 个数据元素的基本操作为:移动指针,比较 j 和 I 。令指针 p 始终指向线性表中第 j 个 数据元素。43v算法描述Status GetElem-L( LinkList L, int i , ElemType &e) /L为带头结点的单链表的头指针 /当第i个元素存在时,其值赋给e并返回OK,否则 返回ERROR p= L-next ; j=1; /初始化,p指向第一个结点,j为 计数器 while( p & ji) p=p-next; j+; if( !p | ji ) return ERROR; /第i个元素不存在 e=p-data; /取第i个元素 return OK; / G。

22、etElem-L44u 算法评价(时间复杂度)若找到值为e结点,p指向该结点 While循环中语句频度为 否则,为表长n T (n ) = O (n )45u插入:在带头结点的单链表L中第i个位置之前插入元素ep a b ep-next=s;ss-next=p-next;可见,在链表中插入结点只需要修改指针。因此,在单链表中第 i 个结点之前进行插入的基本操作为:找到线性表中第i-1个结点,然后修改其指向后继的指针。46u算法描述Status ListInsert-L(LinkList &L,int i,ElemType e) /在带头结点的单链表L中第i个位置之前插入元素e p=L; j=0。

23、; while(p&ji-1) p=p-next; j+; /寻找第i-1个结点 if(!p | ji-1) return ERROR; /i小于1或大于表长 s=(LinkList)malloc(sizeof(Lnode); /生成新结点 s-data=e; s-next=p-next; /插入L中 p-next=s; return OK; /LinstInsert_Lu算法评价(时间复杂度)T (n ) = O (n )47删除:在带头结点的单链表L中删除第i个元素 在单链表中删除第 i 个结点的基本操作为:找 到线性表中第i-1个结点,修改其指向后继的指针。 q = p-next; e 。

24、= q-data; p-next = q-next; free(q);p ai-148q ai ai+1算法描述Status ListDelete-L(LinkList &L, int i, ElemType &e) /在带头结点的单链表L中删除第i个元素,并由e返回其值 p=L; j=0; while(p-next&ji-1) /寻找第i个结点,并令p指向其前驱 p=p-next; j+; if(!(p-next) | (ji-1) return ERROR; /删除位置不合理 q=p-next; p-next=q-next; /删除并释放结点 e=q-data; free(q); retu。

25、rn OK; /ListDelete-L算法评价49T (n ) = O (n )操作 ClearList(&L) 在链表中的实现: void ClearList(&L) / 将单链表重新置为一个空表 while (L-next) p=L-next; L-next=p-next; free(p); / ClearList算法时间复杂度: T ( n ) = O ( n )50如何从线性表得到单链表?链表是一个动态的结构,它不需要给予分配 空间,因此生成链表的过程是一个结点“逐 个插入” 的过程。51例如:逆位序输入 n 个数据元素的值, 建立带头结点的单链表。操作步骤:一、建立一个“空表”; 。

26、二、输入数据元素an,建立结点并插入(sizeof(Lnode); L-next=NULL; /先建立一个带头结点的单链表 for(i=n;i0;i-) p=(LinkList)malloc(sizeof(Lnode); /生成新结点 scanf(&p-data); /输入元素值 p-next=L-next; L-next=p; /插入新元素 /CreateList-Lu 算法评价54T (n ) = O (n )l归并两个有序单链表 算法思想同前MergeList算法。 l 算法描述 /已知单链线性表La和Lb的元素按值非递减排列。 / 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值。

27、非递 减排列 pa=La-next; Lc=pc=La; while( pa & pb ) if( pa-data = pb-data )55void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc)pb=Lb-next; /用La的头结点作为Lc的头结点 pc-next=pa; pc=pa; pa=pa-next; else pc-next=pb; pc=pb; pb=pb-next; pc-next=pa?pa:pb; free( Lb ); /插入剩余段 /释放Lb的头结点 / MergeList_L56采用单链表数据结构的合并算。

28、法与采用线性 表结构的合并算法的区别时间复杂度相同 O( ListLength(La) + ListLength(Lb) 空间复杂度不同 采用单链表数据结构,不需要另建新表的结点 空间,而只需将原来两个链表中结点之间的关系 解除,重新链接。57v单链表特点l它是一种动态结构,整个存储空间为多个 链表共用 l不需预先分配空间 l指针占用额外存储空间 l不能随机存取,查找速度慢 用单链表实现线性表的操作时,存在的问题: 在链表中,元素的“位序”概念淡化,结点的“位 置”概念加强。改进:将基本操作中的“位序 i ”改变为“指针 p ”。58静态链表利用数组描述链表。/-线性表的静态单链表存储结构-#。

29、define MAXSIZE 1000 /链表的最大长度 typedef struct ElemType data; int cur; component, SLinkListMAXSIZE;v说明:假设S为SLinkList型变量,lS0.cur 指示第一个结点在数组中的位置; lSi.cur 指示下一个(i+1)结点的位置; l整型游标i类似动态指针p,即i=Si.cur 等价于 指针后 移 p = p-next;59v静态链表操作l定位函数LocateElemvoid LocateElem_SL(SLinkList S, ElemType e) /在静态单链线性表L中查找第1个值为e的元。

30、素 /若找到,则返回它在L中的位序,否则返回0 i=S0.cur; / i指示表中第一个结点while( i & Si.data !=e) i=Si.cur; /在表中顺链查找 return i; / LocateElem_SL60l插入和删除操作 同单链表的插入和删除操作(见算法2.9、2.10) 不同点:用户自己实现malloc和free函数 为了辩明数组中哪些分量未被使用,将所有未被使 用过以及被删除的分量用游标链成一个备用的链 表,每当进行插入时便从备用链表上取得第一个 结点作为待插入的新结点;反之,在删除时将从 链表中删除下来的结点链接到备用链表上。61示例:静态链表例:集合运算(A。

31、-B)U(B-A)。假设由终端输入集合元 素,先建立表示集合A的静态链表S,而后再输入 集合B的元素的同时查找S表,若存在和B相同的 元素,则从S表中删除,否则将此元素插入S表。 算法思路:设3个过程:(1)将整个数组空间初始化成一个链表, InitSpace_SL;(2)从备用空间取得一个结点, Malloc_SL;(3)将空闲结点链接到备用链表上, Free_SL;62void InitSpace_SL(SLinkList &Space) /将一维数组space中各分量链成一个备用链表, space0.cur为头指针,“0”表示空指针 for(i=0;iMAXSIZE-1;+i) spac。

32、ei.cur=i+1; spaceMAXSIZE-1.cur=0; / InitSpace_SL int Malloc_SL(SLinkList &space) /若备用空间链表非空,则返回分配的结点下标,否则返回0ispace0.cur; if(space0.cur) space0.cur=spacei.cur; return i;63 /Malloc_SLvoid Free_SL(SLinkList &Space, int k) / 将下标为k的空闲结点回收到备用链表 spacek.cur = space0.cur; space0.cur=k; / Free_SL void differe。

33、nce(SLinkList &Space, int &S) / 依次输入集合A和B的元素,在一维数组space中建立表 示集合(A-B)U(B-A)的静态链表,S为其头指针。假设备用 空间足够大, space0.cur为其头指针。 InitSpace_SL(space); /初始化备用空间 S=Malloc_SL(space); /生成S的头结点 r=S; /r指向S的当前最后结点 scanf(m,n); /输入A和B的元素个数64for(j=1; j=m;+j ) /建立集合A的链表 iMalloc_SL(space); /分配结点 scanf(spacei.data); /输入A的元素值 。

34、spacer.cur=i; r=i; /插入到表尾 / for spacer.cur=0; / 尾结点的指针为空 for(j=1; j=n; +j ) /依次输入B的元素,若不在当前 /表中,则插入,否则删除 scanf(b); p=S; k=spaceS.cur /k指向集合A中的第一 /个结点 while(k!=spacer.cur & spacek.data!=b) /在当前表中查找 p=k; k=spacek.cur; /while65if(k=spacer.cur) /当前表中不存在该元素,插入在r所 / 指结点之后,且r的当前位置不变66i=Malloc_SL(space); sp。

35、acei.data=b; spacei.cur=spacer.cur; spacer.cur=i; /if else /该元素已在表中,删除之 spacep.cur=spacek.cur; Free_SL(space,k); if(r=k) r=p; /若删除的是r所指结点,则需修改尾指针 /else / for /differencespace(0:11)算法执行流程示例 假设集合A=c,b,e,g,f,d, B=a,b,n,f ,图(a)表示输 入集合A的元素之后建成 的链表S和备用空间链表 的状况。0S11 2 3 456 7 8 9c b e g f d图(a) 表示A的链表S6710。

36、118 2 3 4 5 6 7 0 9 10 11 0space(0:11) 0 S 1 12 34 567 8 9 10 11c b e g f d a9 8 2 3 4 5 6 7 8 0 9 0 10 11 0插入元素a的过程: 在A中查找,不存在,则(1)i=Malloc_SL(space); / i=8 (2) spacei.data=b; spacei.cur=spacer.cur; (3)spacer.cur=i;68图(b) 插入aspace(0:11) 0 S 1 12 34 567 8 9 10 11c b e g f d a3 9 2 3 4 4 9 5 6 7 8 0 。

37、10 11 0删除元素b的过程: 在A中查找,存在(p=2,k=3),则(1) spacep.cur=spacek.cur; (2) Free_SL(space,k);(3) if(r=k) r=p; /若删除的 是r所指结点,则需修改尾指针69图(c) 删除bspace(0:11) 0 S 1 12 34 567 8 9 10 11c b n e g f d a9 3 2 4 9 8 5 6 7 3 8 0 10 11 0插入元素n 的过程: 在A中查找,不存在,则(1)i=Malloc_SL(space); / i=3 (2) spacei.data=b; spacei.cur=space。

38、r.cur; (3)spacer.cur=i;70图(d) 插入nspace(0:11) 0 S 1 12 34 567 8 9 10 11c n e g f d a6 9 2 4 8 5 6 7 7 9 3 0 10 11 0删除元素f 的过程: 在A中查找,存在(p=5,k=6),则(1) spacep.cur=spacek.cur; (2) Free_SL(space,k);(3) if(r=k) r=p; /若删除的 是r所指结点,则需修改尾指针71图(e) 删除f循环链表(circular linked list)v循环链表是表中最后一个结点的指针指向头结点, 使链表构成环状 v特点。

39、:从表中任一结点出发均可找到表中其他结 点,提高查找效率 v操作与单链表基本一致,判别链表中最后一个结点 的条件不同 l单链表 h-next=NULL /后继是否为空 l循环链表 h-next=h /后继是否为头结点h h 空表72双向链表(double linked list)单链表具有单向性的缺点,在查找某节点的 直接前趋的时间复杂度将达到O(n)。 v结点定义typedef struct Dulnode ElemType data ; struct Dulnode *prior ; struct Dulnode *next ; Dulnode, *Dulinklist ;prior da。

40、ta next73空双向循环链表:L 非空双向循环链表:L A Bab pcp-prior-next = p = p-next-proir;74双向链表的操作特点: “查询” 和单链表相同。“插入” 和“删除”时需要同时修改 两个方向上的指针。75v 删除p-prior-next=p-next; a b Pcp-next-prior=p-prior;76l 算法描述Status ListDelete_Dul(Dullinklist&L, int i,ElemType &e) /删除带头结点的双向循环线性表L的第i个元素,/ i的合法值为1=i=表长。if (!(p=GetElemp_Dul(L。

41、,i)位置指针p/在L中确定第i个元素的return ERROR; /p=NULL,既第i个元素不存在 e=p-data; p-prior-next=p-next; p-next-prior=p-prior; free(p); return OK; / ListDelete_Dul77v插入Pa S x b s-next=p; s-prior = p-prior ; p-prior-next=s; p-prior=s;78l算法描述Status ListInsert_Dul(Dullinklist&L, int i,ElemType e) /在带头结点的双向循环线性表L的第i个位置之前插入元素。

42、e, i的合法值为1=i=表长+1。if (!(p=GetElemp_Dul(L,i) /在L中确定第i个元素的位置指针p79return ERROR; /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; / ListInsert_Dul带头结点的线性链表类型定义typedef struct Lnode /结点类型 ElemType date; 。

43、struct LNode *next ; *Link, *Position;Status MakeNode( Link &p, ElemType e ); / 分配由 p 指向的值为e的结点,并返回OK, / 若分配失败,则返回 ERRORvoid FreeNode( Link &p ); / 释放 p 所指结点80typedef struct /链表类型 Link head,tail; /分别指向线性表中的头结点 和最后一个结点 int len; / 指示线性链表中数据元素的个数 LinkList; 相关操作 见P3781链表的基本操作:结构初始化和销毁结构 Status InitList(。

44、 LinkList &L ); / 构造一个空的线性链表 L / 表长为零。 Status DestroyList( LinkList &L ); / 销毁线性链表 L,L不再存在。O(1)O(n)82引用型操作Status ListEmpty ( LinkList L ); /判表空 int ListLength( LinkList L );/ 求表长O(1) O(1) O(n)Status PriorPos( LinkList L, Link p );/ p指向线性表L中的一个结点,返回p所指结点的直接前驱 /的位置。若无前驱,则返回NULLStatus NextPos ( LinkLis。

45、t L , Link p );O(1)/ p指向线性表L中的一个结点,返回p所指结点的直接后继 /的位置。若无后继,则返回NULLO(1) ElemType GetCurElem ( LinkList p ); / p指向线性表L中的一个结点,返回p所指数据元的值83加工型操作Status ClearList ( LinkList &L ); / 重置 L 为空表 O(n) O(1)Status SetCurElem(Link &p, ElemType e ); / 更新当前指针所指数据元素Status Append ( LinkList &L, Link s ); / 在表尾结点之后链接一串。

46、结点 O(s)Status InsAfter ( LinkList &L, Link p;Elemtype e ); O(1) / 将元素 e 插入在当前指针p之后 Status DelAfter ( LinkList &L, Link p; ElemType& e ); / 删除当前指针p之后的结点 O(1)84示例 Status ListInsert_L( LinkList &L, int i, ElemType e) / 在带头结点的单链线性表L的第i个元素之前插入元 素e if(!LocatePos(L,i-1,h) return ERROR; /i值不合法 if(!MakeNode(。

47、s,e) return ERROR; /结点存储分配 失败 InsFirst(h,s); /对于从第i个结点开始的链表,第i-1 个结点是它的头结点 return OK; / ListInsert_L85Status MergeList_L( LinkList &La, LinkList &Lb, LinkList &Lc, int (*compare)(ElemType, ElemType) /已知单链线性表La和Lb的元素按值非递减排序 /归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减 排列 if(! InitList(Lc) return ERROR; /存储空间分配失败 。

48、ha=GetHead(La); hb= GetHead(Lb); /ha和hb分别指向La和Lb的头结点pa=NextPos(La,ha); pb=NextPos(Lb,hb); /pa和pb分别指向La和Lb中当前结点while(pa & pb) /La和Lb均非空 a=GetCurElem(pa); b=GetCurElem(pb); /a和b为两表中当前比较元素86if(*compare)(a,b)=0) /a=b DelFirst(ha,q); Append(Lc,q); pa=NextPos(La,ha); else /ab DelFirst(hb,q); Append(Lc,q);。

49、 pa=NextPos(Lb,hb); / while if(pa) Append(Lc,pa); /链接La中剩余结点 else Append(Lc,pb); /链接Lb中剩余结点 FreeNode(ha); FreeNode(hb); /释放La和Lb的头结点 return OK; / MergeList_L872.4 线性表的应用举例一元多项式的表示及相加 一元多项式的表示:Pn ( x ) = P0 + P1 x + P2 x2+ L L + Pn xn可用线性表P表示P = ( P0 , P1 , P2 , L L , Pn )1000 20000 + 2x 但对S(x)这样的多项式。

50、浪费空间 S ( x ) = 1 + 3 x一般 Pn ( x )= P1 xe1+ P2 xe2+ L L + Pm xem其中 0 e1 e 2 L L em ( Pi 为非零系数) 用数据域含两个数据项的线性表表示 ( P1, e1 ),P2, e 2 ), L ( Pm , em ) ( L 其存储结构可以用顺序存储结构,也可以用单链表88单链表的结点定义typedef struct node int coef; int exp; struct node *next; JD;coefexpnext89基本操作: CreatPolyn ( &P, m )操作结果:输入 m 项的系数和指数。

51、, 建立一元多项式 P。DestroyPolyn ( &P )初始条件:一元多项式 P 已存在。 操作结果:销毁一元多项式 P。PrintPolyn ( &P )初始条件:一元多项式 P 已存在。 操作结果:打印输出一元多项式 P。90PolynLength( P )初始条件:一元多项式 P 已存在。 操作结果:返回一元多项式 P 中的项数。AddPolyn ( &Pa, &Pb )初始条件:一元多项式 Pa 和 Pb 已存在。 操作结果:完成多项式相加运算,即: Pa = PaPb,并销毁一元多项式 Pb。SubtractPolyn ( &Pa, &Pb ) ADT P算法实现: p43 算。

52、法2.2294Status CreatPolyn ( polynomail &P, int m ) / 输入m项的系数和指数,建立表示一元多项式的有序链表PInitList (P); h=GetHead(P); e.coef = 0.0; e.expn = -1; SetCurElem (h, e); / 设置头结点的数据元素 for ( i=1; i=m; +i ) / 依次输入 m 个非零项 scanf (e.coef, e.expn);if (!LocateElem ( P, e, (*cmp)() ) /当前链表中不存在该指数项 return OK; / CreatPolyn95if 。

53、( MakeNode(s,e)InsAfter ( P, s );注意: 1.输入次序不限;2.指数相同的项只能输入一次。Status AddPolyn (polynomial &Pa, polynomial &Pb) / 利用两个多项式的结点构成“和多项式” Pa = PaPbha=GetHead(Pa); hb=GetHead(Pb);/ha和hb分别指向Pa和Pb的头结点qa=NextPos(Pa,ha); qb=NextPos(Pb,hb);/qa和qb分别指向Pa和Pb中当前结点while(qa & qb) /qa和qb均非空 a=GetCurElem(qa); b=GetCurEl。

54、em(qb);/a和b为两表中当前比较元素9697switch (*cmp(a, b) case -1: / 多项式PA中当前结点的指数值小 ha=qa; qa=NextPos(Pa,qa); break; case 0: / 两者的指数值相等 sum = a.coef + b.coef ; if ( sum != 0.0 ) /修改多项式PA中当前结点的系数值 SetCurElem(qa, sum); ha=qa; else /删除多项式PA中当前结点 DelFirst(ha,qa); FreeNode(qa); DelFirst(hb,qb); FreeNode(qb); qb=NextP。

55、os(Pb,hb); qa=NextPos(Pa,ha); break; case 1: /多项式PB中当前结点的指数值小 DelFirst(hb,qb); InsFirst(ha,qb); qb=NextPos(Pb,hb); ha=NextPos(Pa,ha); break; / switch / whileif(! ListEmpty(Pb) Append(Pa, qb);/链接Pb中剩余结点 FreeNode(hb); /释放Pb的头结点 / AddPolyn98本章小结1.了解线性表的逻辑结构特性是数据元素之间存在 着线性关系,在计算机中表示这种关系的两类不同 的存储结构是顺序存储结构和链式存储结构。用前 者表示的线性表简称为顺序表,用后者表示的线性表简称为链表。 2.熟练掌握这两类存储结构的描述方法,以及线性表的各种基本操作的实现。 3.能够从时间和空间复杂度的角度综合比较线性表两种 存储结构的不同特点及其适用场合。99百度搜索“就爱阅读”,专业资料,生活学习,尽在就爱阅读网92to.com,您的在线图书馆 104。

线性表C语言locate和ETget,线性表(数据结构重难点讲解)相关推荐

  1. 用c语言求解n阶线性,用C语言求解N阶线性矩阵方程Ax=b的简单解法.docx

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp高等教育&nbsp>&nbsp专业基础教材 用C语言求解N阶线性矩阵方程Ax=b的简单解法. ...

  2. 九九乘法表c语言编程java,九九乘法表(c语言和java语言)+心得

    c语言心得 1.c语言并不能代表编程,但学好编程必须要学好c语言 2.编程是一种另类的动手操作能力,遇到事情不要着急向别人"伸手",有事问"度娘"," ...

  3. 99乘法表c语言关于对齐,九九乘法表怎么准确对齐

    九九乘法表怎么准确对齐 九九乘法表怎么准确对齐 日期:2014-05-20 浏览次数:20396 次 九九乘法表如何准确对齐? //九九乘法表 public   class   Chengfabiao ...

  4. 除法口诀表c语言编程,最新除法口诀表打印版

    九九除法口诀表(打印版)_数学_小学教育_教育专区.九九乘法除法口诀表(打印版),一二年级学生适用.希望能帮到家长们 一一得一 1÷1=1 一二得二 二二得四 2÷1=2 4÷2=2 一三得三 二三得 ...

  5. 九九乘法表c语言代码空格,九九乘法表的C语言代码.doc

    int main() { int i=1,j; for (i=1,j=1;j<=9;j++) { if( j==1) printf("%d*%d=%d\n",i,j,i*j) ...

  6. C语言输出汉字版乘法口诀表,C语言实现打印乘法口诀表

    程序代码: for循环嵌套 #include int main() { for(int i=1;i<=9;i++) { for(int j=1;j<=i;j++) { printf(&qu ...

  7. c语言运算符ascii表,C语言运算符优先级和ASCII表

    ExecutorService线程池 ExecutorService 建立多线程的步骤: 1.定义线程类 class Handler implements Runnable{} 2.建立Executo ...

  8. c语言指令保留字,C语言命令令、符号表

    C语言命令令.符号表 C语言命令令.符号表 编译指令 ://-单行注解:/*多行注解*/ 基本数据类型(int,float,double,char,void) 用户自定义数据类型格式 t y p e ...

  9. c语言线性顺序表,C语言程序——线性顺序表.doc

    C语言程序--线性顺序表.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该文 ...

最新文章

  1. 物流系统高可用架构案例
  2. ping 不通 华为三层交换机vlan_华为交换机常用的三种vlan划分方法,一文了解清楚vlan...
  3. 关于 屏幕阅读器 和 sr-only
  4. Emscripten 单词_(第30期:英语教师备课资料) 英文标识记单词 有趣有用又高效...
  5. 此版本的应用程序不支持其项目类型 (.etp)_适用于Microsoft Dynamics 365商业中心的VPS和VJS版本1.8...
  6. PyQt5-菜单栏工具栏状态栏的使用(QMenuBar、QToolBar、QStatusBar)
  7. JavaME程序 Run Anywhere-- 利用反射机制来动态加载声
  8. ant4 多个form 验证_爬虫遇到头疼的验证码?Python实战讲解弹窗处理和验证码识别...
  9. django-url映射给函数给默认值
  10. wx.checkjsapi 一直显示ok_Python下调用json.dumps中文显示问题及解决办法
  11. 【英语学习】【Level 07】U04 Rest and Relaxation L5 An inn by the lake
  12. ctf xor题_CTF下的命令执行
  13. 国内比较好的几大酷站收藏网分享
  14. paip. c++ doxygen 文档工具的使用以及跟QT CREATOR的集成
  15. 推荐Ubuntu使用UML工具-Drawio
  16. MATLAB 电子书
  17. 存储器管理的内存连续分配方式详解
  18. linux网络标志有个问号,只有Linux中的问号
  19. 【Anaconda】修改conda默认envs_dirs和pkgs_dirs
  20. 通过.git/info/exclude文件配置忽略文件

热门文章

  1. [crypto]-50-base64_encode和base64_decode的C语言实现
  2. 用Go语言建立一个简单的区块链part6(2):交易(2)
  3. 2020-11-30(为什么字符串可以赋值给字符指针变量)
  4. HDU2026 首字母变大写
  5. C. Little Girl and Maximum Sum【差分 / 贪心】
  6. 4.2.2 磁盘调度算法
  7. 怎样从0开始搭建一个测试框架_1
  8. Spring boot排除依赖
  9. Spring boot的Hello World入门
  10. Tomcat虚拟主机搭建Web站点