第二章线性表答案
数据结构第2章作业 线性表(答案)

第2章线性表班级学号__________-姓名一、判断正误(×)1. 链表的每个结点中都恰好包含一个指针。
链表中的结点可含多个指针域,分别存放多个指针。
例如,双向链表中的结点可以含有两个指针域,分别存放指向其直接前趋和直接后继结点的指针。
(×)2. 链表的物理存储结构具有同链表一样的顺序。
链表的存储结构特点是无序,而链表的示意图有序。
(×)3. 链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。
链表的结点不会移动,只是指针内容改变。
(×)4. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。
混淆了逻辑结构与物理结构,链表也是线性表!且即使是顺序表,也能存放记录型数据。
(×)5. 顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。
正好说反了。
顺序表才适合随机存取,链表恰恰适于“顺藤摸瓜”(×)6. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。
前一半正确,但后一半说法错误,那是链式存储的优点。
顺序存储方式插入、删除运算效率较低,在表长为n的顺序表中,插入和删除一个数据元素,平均需移动表长一半个数的数据元素。
(×)7. 线性表在物理存储空间中也一定是连续的。
线性表有两种存储方式,顺序存储和链式存储。
后者不要求连续存放。
(×)8. 线性表在顺序存储时,逻辑上相邻的元素未必在存储的物理位置次序上相邻。
线性表有两种存储方式,在顺序存储时,逻辑上相邻的元素在存储的物理位置次序上也相邻。
(×)9. 顺序存储方式只能用于存储线性结构。
顺序存储方式不仅能用于存储线性结构,还可以用来存放非线性结构,例如完全二叉树是属于非线性结构,但其最佳存储方式是顺序存储方式。
(后一节介绍)(×)10. 线性表的逻辑顺序与存储顺序总是一致的。
理由同7。
链式存储就无需一致。
数据结构第二章 线性表练习及答案

一、选择题1、用单链表方式存储的线性表,存储每个结点需要两个域,一个是数据域,另一个是()A、当前结点所在的地址域B、指针域C、空指针域D、空闲域2、不带头结点的单链表head为空的判断条件是()A、head==NULLB、head->next==NULLC、head->data==NULLD、head!=NULL3、在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在p和q之间插入s结点,则执行()A、s->next=p; q->next=s;B、p->next=s->next; s->next=p;C、q->next=s->next; s->next=p;D、p->next=s; s->next=q;4、在一个具有n个结点的有序单链表中插入一个新结点并仍然有序的时间复杂度是()A、O(1)B、O(n)C、O(n2)D、O(nlog2n)5、一个单链表中,若删除p所指结点的后续结点,则执行()A、p->next=p->next->next;B、p=p->next; p->next=p->next->next;C、p->next=p;D、p=p->next->next;6、已知一个顺序存储的基本线性表,设每个结点需占m个存储单元,若第一个结点的地址为d1,则第i个结点的地址为()A、d1+(i-1)*mB、d1+i*mC、d1-i*mD、d1+(i+1)*m7、在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是()A、访问第i个结点(1<=i<=n)和求第i个结点的直接前驱(2<=i<=n)B、在第i个结点后插入一个新结点(1<=i<=n)C、删除第i个结点(1<=i<=n)D、将n个结点从小到大排序8、下面给出的算法段是要把一个q所指新结点作为非空双向链表中的p所指结点的前驱结点插入到该双向链表中,能正确完成要求的算法段是()A、q->next=p; q->prior=p->prior; p->prior=q; p->prior->next=q;B、p->prior=q; q->next=p; p->prior->next=q; q->prior=p->prior;C、q->prior=p->prior; q->next=p; p->prior->next=q; p->prior=q;D、以上都不对9、在循环双链表的p所指结点之后插入s所指结点的操作是()A、p->next=s; s->prior=p; p->next->prior=s; s->next=p->next;B、p->next=s; p->next->prior=s; s->prior=p; s->next=p->next;C、s->prior=p; s->next=p->next; p->next=s; p->next->prior=s;D、s->prior=p; p->next->prior=s; s->next=p->next; p->next=s;10、从具有n个结点的单链表中查找其值等于x结点时,在查找成功的情况下,需平均比较()个结点。
第二章课后作业答案

第二章线性表习题(答案)1.描述以下三个概念的区别:头指针,头结点,首元素结点。
首元结点是指链表中存储线性表中第一个数据元素a1的结点。
为了操作方便,通常在链表的首元结点之前附设一个结点,称为头结点,该结点的数据域中不存储线性表的数据元素,其作用是为了对链表进行操作时,可以对空表、非空表的情况以及对首元结点进行统一处理。
头指针是指向链表中第一个结点(或为头结点或为首元结点)的指针。
若链表中附设头结点,则不管线性表是否为空表,头指针均不为空。
否则表示空表的链表的头指针为空。
2.填空:(1)在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。
(2)在顺序表中,逻辑上相邻的元素,其物理位置也相邻。
在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。
(3)在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点的next域指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋的next域指示。
3.已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。
按要求从下列语句中选择合适的语句序列。
a. 在P结点后插入S结点的语句序列是:(4)、(1)。
b. 在P结点前插入S结点的语句序列是:(7)、(11)、(8)、(4)、(1)。
c. 在表首插入S结点的语句序列是:(5)、(12)。
d. 在表尾插入S结点的语句序列是:(11)、(9)、(1)、(6)。
供选择的语句有:(1)P->next=S; (2)P->next= P->next->next; (3)P->next= S->next;(4)S->next= P->next; (5)S->next= L; (6)S->next= NULL;(7)Q= P; (8)while(P->next!=Q) P=P->next;(9)while(P->next!=NULL) P=P->next; (10)P= Q;(11)P= L; (12)L= S; (13)L= P;4.设线性表存于a[n]中且递增有序。
第二章_线性表(参考答案)

第二章线性表一、填空题1、数据逻辑结构包括线性结构、树型结构、图型结构这三种类型,树形结构和图形结构合称为非线性结构。
2、在线性结构中,第一个结点没有前驱结点,其余每个结点有且只有个前驱结点,最后一个结点没有后续结点,其余每个结点有且只有一个后续结点。
3、在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。
4、在顺序表中,逻辑上相邻的元素,其物理位置一定相邻。
在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。
5、在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点的next域指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋结点的next域指示。
6、阅读下列算法,并补充所缺内容。
void purge_linkst( ListNode *& la ){// 从头指针为 la 的有序链表中删除所有值相同的多余元素,并释放被删结点空间ListNode *p,*q;if(la==NULL) return;q=la; p = la->link;while (p){if (p && ___(1)p->data!=q->data___) {q=p; p = p->link;}else{q->link= ___(2)p->link___;delete(p);p=___(3)q->link___;}}//while}// purge_linkst二、选择题1、在数据结构中,从逻辑上可以把数据结构分成 C。
A、动态结构和静态结构B、紧凑结构和非紧凑结构C、线性结构和非线性结构D、内部结构和外部结构2、线性表的逻辑顺序与存储顺序总是一致的,这种说法 B。
A、正确B、不正确3、线性表若采用链式存储结构时,要求内存中可用存储单元的地址D。
A、必须是连续的B、部分地址必须是连续的C、一定是不连续的D、连续或不连续都可以4、在以下的述叙中,正确的是B。
《数据结构》吕云翔编著第2章线性表习题解答

《数据结构》吕云翔编著第2章线性表习题解答数据结构第2章线性表习题解答一、习题解答1. 假设有一个线性表L={a1, a2, ..., an},设计一种算法,将线性表的所有元素逆置。
解答:可以使用两个指针i和j,分别指向线性表的第一个元素和最后一个元素,然后交换这两个指针所指向的元素,接着i向后移动一个单位,j向前移动一个单位,再次交换他们所指向的元素。
依次类推,直到i和j指针相遇为止。
这样就完成了线性表的逆置。
2. 设线性表L={a1, a2, ..., an},设计一个算法,删除其中所有值为x 的元素。
解答:可以使用一个指针i遍历线性表,当遇到一个元素值等于x 时,将该元素删除,同时将后面的元素依次前移一位。
直到整个线性表遍历完毕。
3. 设有两个线性表LA={a1, a2, ..., am}和LB={b1, b2, ..., bn},其中元素递增有序排列。
设计一个算法,将LA和LB合并成一个新的线性表LC,且元素递增有序排列。
解答:可以使用两个指针i和j分别指向LA和LB的第一个元素,并且使用一个指针k指向LC的最后一个元素。
比较LA[i]和LB[j]的大小,将较小的元素插入到LC的末尾,然后相应指针后移一位,直到其中一个指针到达对应线性表的末尾。
最后,将剩余的元素插入到LC的末尾,即可得到合并后的线性表LC。
4. 设线性表L={a1, a2, ..., an},设计一个算法,找出其中最大的元素以及最大元素的位置。
解答:可以使用一个变量max记录当前遍历到的最大元素,初始化为L[0],同时使用变量position记录最大元素的位置,初始值也为0。
然后遍历整个线性表,若遇到L[i]大于max,则更新max为L[i],同时更新position为i。
遍历完毕后,max就是最大元素,position就是最大元素的位置。
5. 在线性表L={a1, a2, ..., an}中,设计一个算法,找出倒数第k个位置上的元素。
数据结构(C++版)课后答案 (王红梅)第2章 线性表

第 2 章线性表课后习题讲解1. 填空⑴在顺序表中,等概率情况下,插入和删除一个元素平均需移动()个元素,具体移动元素的个数与()和()有关。
【解答】表长的一半,表长,该元素在表中的位置⑵顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的存储地址是()。
【解答】108【分析】第5个元素的存储地址=第1个元素的存储地址+(5-1)×2=108⑶设单链表中指针p 指向结点A,若要删除A的后继结点(假设A存在后继结点),则需修改指针的操作为()。
【解答】p->next=(p->next)->next⑷单链表中设置头结点的作用是()。
【解答】为了运算方便【分析】例如在插入和删除操作时不必对表头的情况进行特殊处理。
⑸非空的单循环链表由头指针head指示,则其尾结点(由指针p所指)满足()。
【解答】p->next=head【分析】如图2-8所示。
⑹在由尾指针rear指示的单循环链表中,在表尾插入一个结点s的操作序列是();删除开始结点的操作序列为()。
【解答】s->next =rear->next; rear->next =s; rear =s;q=rear->next->next; rear->next->next=q->next; delete q;【分析】操作示意图如图2-9所示:⑺一个具有n个结点的单链表,在指针p所指结点后插入一个新结点的时间复杂度为();在给定值为x的结点后插入一个新结点的时间复杂度为()。
【解答】Ο(1),Ο(n)【分析】在p所指结点后插入一个新结点只需修改指针,所以时间复杂度为Ο(1);而在给定值为x的结点后插入一个新结点需要先查找值为x的结点,所以时间复杂度为Ο(n)。
⑻可由一个尾指针唯一确定的链表有()、()、()。
【解答】循环链表,循环双链表,双链表2. 选择题⑴线性表的顺序存储结构是一种()的存储结构,线性表的链接存储结构是一种()的存储结构。
数据结构线性表课后答案

第2章线性表1.选择题(1)顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是()。
A.110 B.108 C.100 D.120答案:B解释:顺序表中的数据连续存储,所以第5个元素的地址为:100+2*4=108。
(2)在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是()。
A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)B.在第i个结点后插入一个新结点(1≤i≤n)C.删除第i个结点(1≤i≤n)D.将n个结点从小到大排序答案:A解释:在顺序表中插入一个结点的时间复杂度都是O(n2),排序的时间复杂度为O(n2)或O(nlog2n)。
顺序表是一种随机存取结构,访问第i个结点和求第i个结点的直接前驱都可以直接通过数组的下标直接定位,时间复杂度是O(1)。
(3)向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动的元素个数为()。
A.8 B.63.5 C.63 D.7答案:B解释:平均要移动的元素个数为:n/2。
(4)链接存储的存储结构所占存储空间()。
A.分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针B.只有一部分,存放结点值C.只有一部分,存储表示结点间关系的指针D.分两部分,一部分存放结点值,另一部分存放结点所占单元数答案:A(5)线性表若采用链式存储结构时,要求内存中可用存储单元的地址()。
A.必须是连续的B.部分地址必须是连续的C.一定是不连续的D.连续或不连续都可以答案:D(6)线性表L在()情况下适用于使用链式结构实现。
A.需经常修改L中的结点值B.需不断对L进行删除插入C.L中含有大量的结点D.L中结点结构复杂答案:B解释:链表最大的优点在于插入和删除时不需要移动数据,直接修改指针即可。
(7)单链表的存储密度()。
A.大于1 B.等于1 C.小于1 D.不能确定答案:C解释:存储密度是指一个结点数据本身所占的存储空间和整个结点所占的存储空间之比,假设单链表一个结点本身所占的空间为D,指针域所占的空间为N,则存储密度为:D/(D+N),一定小于1。
第2章 线性表习题参考答案

习题二参考答案一、选择题1.链式存储结构的最大优点是( D )。
A.便于随机存取B.存储密度高C.无需预分配空间D.便于进行插入和删除操作2.假设在顺序表{a0,a1,……,a n-1}中,每一个数据元素所占的存储单元的数目为4,且第0个数据元素的存储地址为100,则第7个数据元素的存储地址是( D )。
A.106B. 107C.124D.1283.在线性表中若经常要存取第i个数据元素及其前趋,则宜采用( A )存储方式。
A.顺序表B. 带头结点的单链表C.不带头结点的单链表D. 循环单链表4.在链表中若经常要删除表中最后一个结点或在最后一个结点之后插入一个新结点,则宜采用( C )存储方式。
A.顺序表B. 用头指针标识的循环单链表C. 用尾指针标识的循环单链表D. 双向链表5.在一个单链表中的p和q两个结点之间插入一个新结点,假设新结点为S,则修改链的java语句序列是( D )。
A.s.setNext(p); q.setNext(s);B. p.setNext(s.getNext()); s.setNext(p);C. q.setNext(s.getNext()); s.setNext(p);D. p.setNext(s); s.setNext(q);6.在一个含有n个结点的有序单链表中插入一个新结点,使单链表仍然保持有序的算法的时间复杂度是( C )。
A.O(1)B. O(log2n)C. O(n)D. O(n2)7.要将一个顺序表{a0,a1,……,a n-1}中第i个数据元素a i(0≤i≤n-1)删除,需要移动( B )个数据元素。
A.iB. n-i-1C. n-iD. n-i+18.在带头结点的双向循环链表中的p结点之后插入一个新结点s,其修改链的java语句序列是( D )。
A.p.setNext(s); s.setPrior(p); p.getNext().setPrior(s);s.setNext(p.getPrior());B.p.setNext(s); p.getNext().setPrior(s); s.setPrior(p);s.setNext(p.getNext());C.s.setPrior(p); s.setNext(p.getNext()); p.setNext(s);p.getNext().setPrior(s);D.s.setNext(p.getNext()); s.setPrior(p); p.getNext().setPrior(s);p.setNext(s);9.顺序表的存储密度是( B ),而单链表的存储密度是( A )。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.11 设顺序表va中的数据元素递增有序。
试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。
Status OrderListInsert-sq(SqList va, ElemType x) {//将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法1)if (va.length==va.listsize){newbase=(ElemType*)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType));if (!newbase) exit(OVERFLOW);va.elem=newbase;va.listsize+=LISTINCREMENT;}//当前存储空间已满,增加分配空间if (!va.length) {va.elem[0]=x; ++va.length; return OK;}q=&(va.elem[0]);while (*q<=x)&&(q<=&(va.elem[va.length-1])) ++q; //查找插入位置for (p=&(va.elem[va.length-1]); p>=q; --p) *(p+1)=*p;*q=x;++va.length;return OK;}//OrderListInsert-sqStatus OrderListInsert-sq(SqList va, ElemType x) {//将x插入到递增有序的顺序表va中,插入后va仍然递增有序(算法2)if (va.length==va.listsize){newbase=(ElemType*)realloc(va.elem,(va.listsize+LISTINCREMENT)*sizeof(ElemType));if (!newbase) exit(OVERFLOW);va.elem=newbase;va.listsize+=LISTINCREMENT;}//当前存储空间已满,增加分配空间if (!va.length) {va.elem[0]=x; ++va.length; return OK;}p=&(va.elem[va.length-1]);while (P>=&(va.elem[0])&&*p>x) {*(p+1)=*p; --p;}*(p+1)=x;++va.length;return OK;}//OrderListInsert-sq2.12 设A=(a1,...,a m)和B=(b1,...,b n)均为顺序表,A'和B'分别为A和B中除去最大共同前缀后的子表。
若A'=B'=空表,则A=B;若A'=空表,而B'≠空表,或者两者均不为空表,且A'的首元小于B'的首元,则A<B;否则A>B。
试写一个比较A,B大小的算法。
int Compare-List(SqList a, SqList b){//a,b为顺序表,若a<b时,返回-1;a=b时,返回0;a>b时,返回1i=0;while (i<=a.length-1) && (i<=b.length-1) && (a.elem[i]=b.elem[i]) ++i;switch {case i=a.length && i=b.length : return 0; break;case (i=a.length && i<=b.length-1)||(i<=a.length-1 && i<=b.length-1 && a.elem[i]<b.elem[i]) : return -1;break; default : return 1;}}//Compare-List2.19status del-l(LinkList &la, int mink, int maxk){//la为带头结点的单链表的头指针,单链表中的结点以值递增有序排列//本算法删除表中所有值大于mink且小于maxk的元素,mink<maxkif (mink>=maxk) return ERRORp=la;while (p->next<>NULL && p->next->data<=mink) p=p->next;q=p;while (q->next<>NULL && q->next->data<maxk) q=q->next ;q=q->next;p1=p->next;while (p1<>q) {q1=p1; p1=p1->next; free(q1);}}//del-l2.21LinkList priou(LinkList la, LinkList q1){//返回指向单链表la中结点的指针p1,p1->next=q1 p1=la;while (p1->next!=q1) p1=p1->next;return p1;}//priouvoid Reverse-List-l(LinkList &la) {//就地逆置单链表la(算法1)if (!la->next) return;p=la->next; q=priou(la, NULL);while (p!=q) {p->data〈-〉q->data;if (p=q) return;q=priou(la, q);}}//Reverse-List-lvoid Reverse-List-l(LinkList &la) {//就地逆置单链表la(算法2)p=priou(la, NULL); last=p;pre=priou(la,p);while (pre!=la) {p=pre;pre=priou(la,p);}p->next=NULL;la->next=last;}//Reverse-List-lvoid Reverse-List-l(LinkList &la) { //就地逆置单链表la(算法3)if (!la->next) return;pre=la->next;if (!pre->next) return;p=pre->next; pre->next=NULL; next=p->next;while (p) {p->next=pre;pre=p;p=next;if (p) next=p->next;}la->next=pre;return;}//Reverse-List-lvoid Reverse-List-l(LinkList &la) { //就地逆置单链表la(算法4)if (!p || !p->next) return;pn=p->next; p->next=NULL;while (pn) {p=pn; pn=pn->next;p->next=la->next; la->next=p;}return;}//Reverse-List-l2.24void MergeList(LinkList &a, LinkList &b, LinkList &c) {//已知单链表a和b的元素按值递增有序排列//归并a和b得到新的单链表c,c的元素按值递减有序c=a; p=a->next; q=b->next; c->next=NULL;while (p && q)if (p->data<q->data) {pn=p->next; p->next=c->next;c->next=p; p=pn;}else {qn=q->next; q->next=c->next;c->next=q; q=qn;}while (p) {pn=p->next; p->next=c->next; c->next=p; p=pn;} while (q) {qn=q->next; q->next=c->next; c->next=q; q=qn;} free(b);}//MergeList2.33void CutApart-LinkList(LinkList &l, LinkList la, LinkList lb, LinkList lc){//单链表l中的元素含有三类字符:字母、数字和其它字符//本算法将l分割为la、lb和lc三个循环链表,它们分别只含字母、数字和其它字符la=(LinkList)malloc(sizeof(LNode)); la->next=la;lb=(LinkList)malloc(sizeof(LNode)); lb->next=lb;lc=(LinkList)malloc(sizeof(LNode)); lc->next=lc;pn=l->next;while (pn){p=pn; pn=pn->next;switch {case ('a'<=p->data && p->data<='z')||('A'<=p->data && p->data<='Z') : p->next=la->next; la->next=p; break;case ('0'<=p->data && p->data<='9') : p->next=lb->next; lb->next=p; break;default : p->next=lc->next; lc->next=p;}//switch}//whilefree(l);}//CutApart-LinkList2.39typedef struct {float coef;int expn;}*Poly, ElemType;float Polynomial(Poly &p, int m, float x0){//多项式p的顺序存储结构中依次存放有c1,e1,c2,e2,...,c m,e m//x0为给定值,本算法计算p n(x0)的值x=x0^p[0].expn;pn=p[0].coef*x;for (i=1; i<=m; ++i){x=x*x0^(p[i].expn-p[i-1].expn);pn=pn+p[i].coef*x;}retrun pn;}//Polynomial(以下内容来自)第二章线性表2.10Status DeleteK(SqList &a,int i,int k)//删除线性表a中第i个元素起的k个元素{if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;for(count=1;i+count-1<=a.length-k;count++) //注意循环结束的条件a.elem[i+count-1]=a.elem[i+count+k-1];a.length-=k;return OK;}//DeleteK2.11Status Insert_SqList(SqList &va,int x)//把x插入递增有序表va中{if(va.length+1>va.listsize) return ERROR;va.length++;for(i=va.length-1;va.elem[i]>x&&i>=0;i--)va.elem[i+1]=va.elem[i];va.elem[i+1]=x;return OK;}//Insert_SqList2.12int ListComp(SqList A,SqList B)//比较字符表A和B,并用返回值表示结果,值为正,表示A>B;值为负,表示A<B;值为零,表示A=B{for(i=1;A.elem[i]||B.elem[i];i++)if(A.elem[i]!=B.elem[i]) return A.elem[i]-B.elem[i];return 0;}//ListComp2.13LNode* Locate(LinkList L,int x)//链表上的元素查找,返回指针{for(p=l->next;p&&p->data!=x;p=p->next);return p;}//Locate2.14int Length(LinkList L)//求链表的长度{for(k=0,p=L;p->next;p=p->next,k++);return k;}//Length2.15void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把链表hb接在ha后面形成链表hc{hc=ha;p=ha;while(p->next) p=p->next;p->next=hb;}//ListConcat2.16见书后答案.2.17Status Insert(LinkList &L,int i,int b)//在无头结点链表L的第i个元素之前插入元素b{p=L;q=(LinkList*)malloc(sizeof(LNode));q.data=b;if(i==1){q.next=p;L=q; //插入在链表头部}else{while(--i>1) p=p->next;q->next=p->next;p->next=q; //插入在第i个元素的位置}}//Insert2.18Status Delete(LinkList &L,int i)//在无头结点链表L中删除第i个元素{if(i==1) L=L->next; //删除第一个元素else{p=L;while(--i>1) p=p->next;p->next=p->next->next; //删除第i个元素}}//Delete2.19Status Delete_Between(Linklist &L,int mink,int maxk)//删除元素递增排列的链表L中值大于mink且小于maxk的所有元素{p=L;while(p->next->data<=mink) p=p->next; //p是最后一个不大于mink的元素if(p->next) //如果还有比mink更大的元素{q=p->next;while(q->data<maxk) q=q->next; //q是第一个不小于maxk的元素p->next=q;}}//Delete_Between2.20Status Delete_Equal(Linklist &L)//删除元素递增排列的链表L中所有值相同的元素{p=L->next;q=p->next; //p,q指向相邻两元素while(p->next){if(p->data!=q->data){p=p->next;q=p->next; //当相邻两元素不相等时,p,q都向后推一步}else{while(q->data==p->data) q=q->next;p->next=q;p=q;q=p->next; //当相邻元素相等时删除多余元素}}//while}//Delete_Equal2.21void reverse(SqList &A)//顺序表的就地逆置{for(i=1,j=A.length;i<j;i++,j--)A.elem[i]<->A.elem[j];}//reverse2.22void LinkList_reverse(Linklist &L)//链表的就地逆置;为简化算法,假设表长大于2 {p=L->next;q=p->next;s=q->next;p->next=NULL;while(s->next){q->next=p;p=q;q=s;s=s->next; //把L的元素逐个插入新表表头}q->next=p;s->next=q;A->next=s;}//LinkList_reverse分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.2.23void merge1(LinkList &A,LinkList &B,LinkList &C)//把链表A和B合并为C,A和B的元素间隔排列,且使用原存储空间{p=A->next;q=B->next;C=A;while(p&&q){s=p->next;p->next=q; //将B的元素插入if(s){t=q->next;q->next=s; //如A非空,将A的元素插入}p=s;q=t;}//while}//merge12.24void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素递增排列的链表A和B合并为C,且C中元素递减排列,使用原空间{pa=A->next;pb=B->next;pre=NULL; //pa和pb分别指向A,B的当前元素while(pa&&pb){if(pa->data<pb->data){pc=pa;q=pa->next;pa->next=pre;pa=q; //将A的元素插入新表}else{pc=pb;q=pb->next;pb->next=pre;pb=q; //将B的元素插入新表}pre=pc;}while(pa){q=pa->next;pa->next=pc;pc=pa;pa=q; //插入A中余下的元素}while(pb){q=pb->next;pb->next=pc;pc=pb;pb=q; //插入B中余下的元素}C=A;A->next=pc; //构造新表头}//reverse_merge分析:本算法的思想是,按从小到大的顺序依次把A和B的元素插入新表的头部pc处,最后处理A或B的剩余元素.2.25void SqList_Intersect(SqList A,SqList B,SqList &C)//求元素递增排列的线性表A 和B的元素的交集并存入C中{i=1;j=1;k=0;while(A.elem[i]&&B.elem[j]){if(A.elem[i]<B.elem[j]) i++;if(A.elem[i]>B.elem[j]) j++;if(A.elem[i]==B.elem[j]){C.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素,i++;j++; //就添加到C中}}//while}//SqList_Intersect2.26void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在链表结构上重做上题{p=A->next;q=B->next;pc=(LNode*)malloc(sizeof(LNode));while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else{s=(LNode*)malloc(sizeof(LNode));s->data=p->data;pc->next=s;pc=s;p=p->next;q=q->next;}}//whileC=pc;}//LinkList_Intersect2.27void SqList_Intersect_True(SqList &A,SqList B)//求元素递增排列的线性表A和B的元素的交集并存回A中{i=1;j=1;k=0;while(A.elem[i]&&B.elem[j]){if(A.elem[i]<B.elem[j]) i++;else if(A.elem[i]!=A.elem[k]){A.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素i++;j++; //且C中没有,就添加到C中}}//whilewhile(A.elem[k]) A.elem[k++]=0;}//SqList_Intersect_True2.28void LinkList_Intersect_True(LinkList &A,LinkList B)//在链表结构上重做上题{p=A->next;q=B->next;pc=A;while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else if(p->data!=pc->data){pc=pc->next;pc->data=p->data;p=p->next;q=q->next;}}//while}//LinkList_Intersect_True2.29void SqList_Intersect_delete(SqList &A,SqList B,SqList C)//从有序顺序表A中删除那些在B和C中都出现的元素{i=1;j=1;k=1;while(B.elem[i]&&C.elem[j]){if(B.elem[i]<C.elem[j]) i++;else //找到了需要从A中删除的元素{u=B.elem[i];while(A.elem[k]<u) k++;for(;A.elem[k]==u;k++)A.elem[k]=INFINITY; //把A中待删除元素置换为特殊记号while(B.elem[i]==u) i++;while(C.elem[j]==u) j++;}//else}//whilefor(i=1,j=1;j<=A.length;i++) //第二遍扫描A,删除特殊记号{while(A.elem[j]==INFINITY){j++;A.length--;}if(i<j) A.elem[i]=A.elem[j];//执行"紧缩"操作j++;}//for}//SqList_Intersect_delete分析:本算法的时间复杂度为O(m),m为表长.思考:你自己的算法时间复杂度是多少?实际上也可以只用一遍扫描就完成整个操作,且时间复杂度也为O(m),但非常复杂,你能写出来吗?2.30void LinkList_Intersect_delete(LinkList &A,LinkList B,LinkList C)//在链表结构上重做上题{p=B->next;q=C->next;r=A-next;while(p&&q&&r){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else{u=p->data; //确定待删除元素uwhile(r->next->data<u) r=r->next; //确定最后一个小于u的元素指针r if(r->next->data==u){s=r->next;while(s->data==u){t=s;s=s->next;free(t); //确定第一个大于u的元素指针s}//whiler->next=s; //删除r和s之间的元素}//ifwhile(p->data=u) p=p->next;while(q->data=u) q=q->next;}//else}//while}//LinkList_Intersect_delete2.31Status Delete_Pre(CiLNode *s)//删除单循环链表中结点s的直接前驱{p=s;while(p->next->next!=s) p=p->next; //找到s的前驱的前驱pp->next=s;return OK;}//Delete_pre2.32Status DuLNode_pre(DuLinkList &L)//完成双向循环链表结点的pre域{for(p=L;!p->next->pre;p=p->next) p->next->pre=p;return OK;}//DuLNode_pre2.33Status LinkList_divide(LinkList &L,CiList &A,CiList &B,CiList &C)//把单链表L 的元素按类型分为三个循环链表.CiList为带头结点的单循环链表类型.{s=L->next;A=(CiList*)malloc(sizeof(CiLNode));p=A;B=(CiList*)malloc(sizeof(CiLNode));q=B;C=(CiList*)malloc(sizeof(CiLNode));r=C; //建立头结点while(s){if(isalphabet(s->data)){p->next=s;p=s;}else if(isdigit(s->data)){q->next=s;q=s;}else{r->next=s;r=s;}}//whilep->next=A;q->next=B;r->next=C; //完成循环链表}//LinkList_divide2.34void Print_XorLinkedList(XorLinkedList L)//从左向右输出异或链表的元素值{p=L.left;pre=NULL;while(p){printf("%d",p->data);q=XorP(p->LRPtr,pre);pre=p;p=q; //任何一个结点的LRPtr域值与其左结点指针进行异或运算即得到其右结点指针}}//Print_XorLinkedList2.35Status Insert_XorLinkedList(XorLinkedList &L,int x,int i)//在异或链表L的第i个元素前插入元素x{p=L.left;pre=NULL;r=(XorNode*)malloc(sizeof(XorNode));r->data=x;if(i==1) //当插入点在最左边的情况{p->LRPtr=XorP(p.LRPtr,r);r->LRPtr=p;L.left=r;return OK;}j=1;q=p->LRPtr; //当插入点在中间的情况while(++j<i&&q){q=XorP(p->LRPtr,pre);pre=p;p=q;}//while //在p,q两结点之间插入if(!q) return INFEASIBLE; //i不可以超过表长p->LRPtr=XorP(XorP(p->LRPtr,q),r);q->LRPtr=XorP(XorP(q->LRPtr,p),r);r->LRPtr=XorP(p,q); //修改指针return OK;}//Insert_XorLinkedList2.36Status Delete_XorLinkedList(XorlinkedList &L,int i)//删除异或链表L的第i个元素{p=L.left;pre=NULL;if(i==1) //删除最左结点的情况{q=p->LRPtr;q->LRPtr=XorP(q->LRPtr,p);L.left=q;free(p);return OK;}j=1;q=p->LRPtr;while(++j<i&&q){q=XorP(p->LRPtr,pre);pre=p;p=q;}//while //找到待删结点qif(!q) return INFEASIBLE; //i不可以超过表长if(L.right==q) //q为最右结点的情况{p->LRPtr=XorP(p->LRPtr,q);L.right=p;free(q);return OK;}r=XorP(q->LRPtr,p); //q为中间结点的情况,此时p,r分别为其左右结点p->LRPtr=XorP(XorP(p->LRPtr,q),r);r->LRPtr=XorP(XorP(r->LRPtr,q),p); //修改指针free(q);return OK;}//Delete_XorLinkedList2.37void reform(DuLinkedList &L)//按1,3,5,...4,2的顺序重排双向循环链表L中的所有结点{p=L.next;while(p->next!=L&&p->next->next!=L){p->next=p->next->next;p=p->next;} //此时p指向最后一个奇数结点if(p->next==L) p->next=L->pre->pre;else p->next=l->pre;p=p->next; //此时p指向最后一个偶数结点while(p->pre->pre!=L){p->next=p->pre->pre;p=p->next;}p->next=L; //按题目要求调整了next链的结构,此时pre链仍为原状for(p=L;p->next!=L;p=p->next) p->next->pre=p;L->pre=p; //调整pre链的结构,同2.32方法}//reform分析:next链和pre链的调整只能分开进行.如同时进行调整的话,必须使用堆栈保存偶数结点的指针,否则将会破坏链表结构,造成结点丢失.2.38DuLNode* LOCATE(DuLinkedList &L,int x)//带freq域的双向循环链表上的查找{p=L.next;while(p.data!=x&&p!=L) p=p->next;if(p==L) return NULL; //没找到p->freq++;q=p->pre;while(q->freq<=p->freq) q=q->pre; //查找插入位置if(q!=p->pre){p->pre->next=p->next;p->next->pre=p->pre;q->next->pre=p;p->next=q->next;q->next=p;p->pre=q; //调整位置}return p;}//LOCATE2.39float GetValue_SqPoly(SqPoly P,int x0)//求升幂顺序存储的稀疏多项式的值{PolyTerm *q;xp=1;q=P.data;sum=0;ex=0;while(q->coef){while(ex<q->exp) xp*=x0;sum+=q->coef*xp;q++;}return sum;}//GetValue_SqPoly2.40void Subtract_SqPoly(SqPoly P1,SqPoly P2,SqPoly &P3)//求稀疏多项式P1减P2的差式P3{PolyTerm *p,*q,*r;Create_SqPoly(P3); //建立空多项式P3p=P1.data;q=P2.data;r=P3.data;while(p->coef&&q->coef){if(p->exp<q->exp){r->coef=p->coef;r->exp=p->exp;p++;r++;}else if(p->exp<q->exp){r->coef=-q->coef;r->exp=q->exp;q++;r++;}else{if((p->coef-q->coef)!=0) //只有同次项相减不为零时才需要存入P3中{r->coef=p->coef-q->coef;r->exp=p->exp;r++;}//ifp++;q++;}//else}//whilewhile(p->coef) //处理P1或P2的剩余项{r->coef=p->coef;r->exp=p->exp;p++;r++;}while(q->coef){r->coef=-q->coef;r->exp=q->exp;q++;r++;}}//Subtract_SqPoly2.41void QiuDao_LinkedPoly(LinkedPoly &L)//对有头结点循环链表结构存储的稀疏多项式L求导{p=L->next;if(!p->data.exp)L->next=p->next;p=p->next; //跳过常数项}while(p!=L){p->data.coef*=p->data.exp--;//对每一项求导p=p->next;}}//QiuDao_LinkedPoly2.42void Divide_LinkedPoly(LinkedPoly &L,&A,&B)//把循环链表存储的稀疏多项式L拆成只含奇次项的A和只含偶次项的B{p=L->next;A=(PolyNode*)malloc(sizeof(PolyNode));B=(PolyNode*)malloc(sizeof(PolyNode));pa=A;pb=B;while(p!=L){if(p->data.exp!=2*(p->data.exp/2)){pa->next=p;pa=p;}else{pb->next=p;pb=p;}p=p->next;}//whilepa->next=A;pb->next=B;}//Divide_LinkedPoly。