1.单链表的结构体定义
1 2 3 4 typedef struct LNode { int data; struct LNode *next ; }LNode,*LinkList;
单链表的初始化
1 2 3 4 void InitList (LinkList &L) { L=(LinkList)malloc (sizeof (LNode)); L->next=NULL ; }
1 2 3 void InitList (LinkList &L) { L=NULL ; }
2.单链表的遍历
题目:遍历输出带头结点的单链表L中各结点数据域的值
思路:定义遍历指针p,初始化为第一个数据节点的位置,也就是头结点指针域指向的地方,遍历输出
1 2 3 4 5 6 7 8 9 void ListVisit (LinkList L) { if (L->next==NULL ) return ; LNode *p=L->next; while (p!=NULL ){ printf ("%d " ,p->data); p=p->next; } }时间复杂度和空间复杂度分别为:O(n)和O(1 )
3.计算单链表的长度
题目:计算带头结点的单链表L中数据结点的个数
思路:遍历+计数
1 2 3 4 5 6 7 8 9 10 11 int Length (LinkList L) { if (L->next==NULL ) return ; LNode *p=L->next; int length=0 ; while (p!=NULL ){ length++; p=p->next; } return length; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
4.单链表的按序查找
题目:请设计一个算法,查找一个带头结点的单链表L中第i个数据结点的位置,若存在,则返回指向该结点的指针,若不存在,则返回NULL
思路:遍历+计数
1 2 3 4 5 6 7 8 9 10 11 12 13 LNode *Search_i (LinkList L,int i) { if (L->next==NULL ||i<1 ) return NULL ; LNode *p=L->next; int k=1 ; while (p!=NULL ){ if (k==i) return p; p=p->next; k++; } return NULL ; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
5.单链表的按值查找
题目:请设计一个算法,查找一个带头结点的单链表L中第1个值为e的结点位置,若存在,则返回指向该结点的指针,若不存在,则返回NULL
思路:遍历
1 2 3 4 5 6 7 8 9 10 11 LNode *Search_e (LinkList L,int e) { if (L->next==NULL ) return NULL ; LNode *p=L->next; while (p!=NULL ){ if (p->data==e) return p; p=p->next; } return NULL ; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
6.有序单链表插入一个新结点后依然有序
题目:在一个带头结点的非递减有序单链表中插入一个值为x的新结点,使得插入新结点后链表依然非递减有序
思路:pre指向头结点,p指向第一个数据元素,若空表则p初始化为NULL直接插入,遍历找到第一个比x大的元素,将x插入该元素之前
1 2 3 4 5 6 7 8 9 10 11 12 13 void ListInsert (LinkList L,int x) { LNode *pre=L,p=L->next; while (p!=NULL ){ if (p->data>x) break ; pre=p; p=p->next; } LNode *s=(LinkList)malloc (sizeof (LNode)); s->data=x; pre->next=s; s->next=p; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
7.头插法建立单链表
题目:采用头插法在头指针工处建立一个带头结点的单链表,输入-1表示结束,头插结束后返回建立的
单链表。
思路:将新节点插在头结点之后,初始化时要将头结点置空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 LinkList HeadInsert (LinkList &L) { L=(LinkList)malloc (sizeof (LNode)); L->next=NULL ; LNode *s; int x; scanf ("%d" ,&x); while (x!=-1 ){ s=(LinkList)malloc (sizeof (LNode)); s->data=x; s->next=L->next; L->next=s; scanf ("%d" ,&x); } return L; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
8.尾插法建立单链表
题目:采用尾插法在头指针L处建立一个带头结点的单链表,输入-1表示结束,尾插结束后返回建立的单链表
思路:将新节点插在尾结点之后,插入结束后将尾指针置空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 LinkList TailInsert (LinkList &L) { L=(LinkList)malloc (sizeof (LNode)); LNode *r=L; LNode *s; int x; scanf ("%d" ,&x); while (x!=-1 ){ s=(LinkList)malloc (sizeof (LNode)); s->data=x; r->next=s; r=s; scanf ("%d" ,&x); } r->next=NULL ; return L; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
9.单链表的逆置
题目:试编写算法将一个带头结点的单链表L就地逆置,所谓“就地"是指空间复杂度为O(1)
思路:头插法将单链表逆置(放断链指针)
1 2 3 4 5 6 7 8 9 10 11 12 13 void Reverse (LinkList L) { if (L->next==NULL ) return ; LNode *p=L->next,*r; L->next=NULL ; while (p!=NULL ){ r=p->next; p->next=L->next; L->next=p; p=r; } }时间复杂度和空间复杂度分别为:O(n)和O(1 )
10.一个单链表按位序分解为两个单链表(尾插+尾插)
题目:将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使得A表中含有原表中位序为奇数的结点,B表中含有原表中位序为偶数的结点,且保持结点间相对顺序不变,最后返回B表
思路:尾插法(两个元素为一组进行尾插)(尾结点置空)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 LinkList Create_A_B (LinkList A) { if (A->next==NULL ) return NULL : LinkList B=(LinkList)malloc (sizeof (LNode)); LNode *p=A->next,*ra=A,*rb=B; while (p!=NUll){ ra->next=p; ra=p; p=p->next; if (p!=NULL ){ rb->next=p; rb=p; p=p->next; } } ra->next=NULL ; rb->next=NULL ; return B; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
11.一个单链表按位序分解为两个单链表(尾插+头插)
题目:编写算法将一个带头结点的单链表A={a1,b1,a2,b2,…,an,bn}分解为两个带头结点的单链表A和B,使得A={a1,a2,…,an},B={bn,…,b2,b1},原A表中结点个数不一定为偶数
思路:A表尾插,B表头插,尾插注意尾结点置空,头插注意放断链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 LinkList Create_A_B (LinkList A) { if (A->next==NULL ) return NULL : LinkList B=(LinkList)malloc (sizeof (LNode)); B->next=NULL ; LNode *p=A->next,*r=A,*q; while (p!=NULL ){ r->next=p; r=p; p=p->next; if (p!=NULL ){ q=p->next; p->next=B->next; B->next=p; p=q; } } r->next=NULL ; return B; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
12.一个单链表按结点值的奇偶分解为两个单链表(尾插+尾插)
题目:将一个带头结点的单链表L分解为两个带头结点的单链表A和B,使得A表中含有原表中数据域为奇数的结点,而B表中含有原表中数据域为偶数的结点,且保持相对顺序不变,最后删除单链表L的头结点
思路:尾插法(尾结点置空)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 LinkList Create_A_B (LinkList L,LinkList &A,LinkList &B) { if (A->next==NULL ) return NULL : LinkList A=(LinkList)malloc (sizeof (LNode)); LinkList B=(LinkList)malloc (sizeof (LNode)); LNode *p=L->next,*ra=A,*rb=B; while (p!=NULL ){ if (p->data%2 ==1 ){ ra->next=p; ra=p; p=p->next; } else { rb->next=p; rb=p; p=p->next; } } A->next=NULL ; B->next=NULL ; free (L); }时间复杂度和空间复杂度分别为:O(n)和O(1 )
13.删除链表中的最小值结点
题目:有一个带头结点单链表L,L中各个结点的值都不相同,请设计一个算法,删除链表L中的最小值结点
思路:遍历找到最小值结点,记录该节点以及其前驱结点,删除最小值结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void Del_Min (LinkList L) { if (L->next==NULL ) return ; LNode *minpre=L,*minp=L->next; LNode *pre=L->next,*p=pre->next; while (p!=NULL ){ if (p->data<minp->data){ minp=p; minpre=pre; } pre=p; p=pre->next; } minpre->next=minp->next; free (minp); }时间复杂度和空间复杂度分别为:O(n)和O(1 )
14.删除单链表中删除所有值为x的结点
题目:请设计一个算法,在带头结点的单链表L中删除所有值为x的结点,并释放其空间
思路:遍历删除所有等于x的结点(需用到其前驱结点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void Del_x (LinkList L,int x) { if (L->next==NULL ) return ; LNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data==x){ pre->next=p->next; free (p); p=pre->next; } else { pre=p; p=pre->next; } } }时间复杂度和空间复杂度分别为:O(n)和O(1 )
15.删除单链表中所有数据域的值介于给定的两个值之间的结点
题目:请设计一个算法,在带头结点的单链表L中删除所有数据域的值介于给定的两个值之间的结点并释放其空间
思路:遍历删除所有大于s小于t的结点(需用到其前驱结点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void Del_s_t (LinkList L,int s,int t) { if (L->next==NULL ||s>=t) return ; LNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data>s&&p->data<t){ pre->next=p->next; free (p); p=pre->next; } else { pre=p; p=pre->next; } } }时间复杂度和空间复杂度分别为:O(n)和O(1 )
16.删除非递减有序链表中所有值重复的结点
题目:请设计一个算法,在带头结点的非递减有序单链表L中删除所有值重复的结点,使值重复的结点只保留一个
思路:遍历删除所有跟其前驱结点数据域相等的的结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void Del_Same (LinkList L) { if (L->next==NULL ) return ; LNode *pre=L-next,*p=pre->next; while (p!=NULL ){ if (p->data>s==pre->data){ pre->next=p->next; free (p); p=pre->next; } else { pre=p; p=pre->next; } } }时间复杂度和空间复杂度分别为:O(n)和O(1 )
17.删除无序链表中所有值重复的结点
题目:请设计一个算法,在带头结点的无序单链表L中删除所有值重复的结点,使值重复的结点只保留一个
思路:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 void Del_Same (LinkList L) { if (L->next==NULL ) return ; LNode *r=L->next; LNode *pre,*p; while (r!=NULL ){ pre=r; p=pre->next; while (p!=NULL ){ if (p->data==r->data){ pre->next=p->next; free (p); p=pre->next; } else { pre=p; p=pre->next; } } r=r->next; } }时间复杂度和空间复杂度分别为:O(n^2 )和O(1 )
18.两个递增有序单链表求交集生成新链表
题目:设A和B是带头结点的递增有序单链表,请设计一个算法,求单链表A与B的交集,并生成个新的单链表C,要求不破坏A、B的结点
思路:同时遍历两表,找出遍历元素中的较大值,让较小的元素后移,与较大值看齐,便可找到两链表中值相同结点,插入C表,尾插法需要尾指针以及最后尾结点置空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 LinkList Union (LinkList A,LinkList B) { if (A->next==NULL ||B->next==NULL ) return NULL ; LNOde *p=A->next,*q=B->next,*r; LNode *s; LinkList C=(LinkList)malloc (sizeof (LNode)); r=C; while (p!=NULL &&q!=NULL ){ if (p->data<q->data) p=p->next; else if (p->data>q->data) q=q->next; else { s=(LinkList)malloc (sizeof (LNode)); s->data=p->data; r->next=s; r=s; p=p->next; q=q->next; } } r->next=NULL ; return C; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
19.两个递增有序单链表求交集存放到原链表
题目:设A和B是两个带头结点的递增有序单链表,请设计一个算法,求单链表A与B的交集,并存放于A链表中,其它结点均释放其空间
思路:同时遍历两表,找出遍历元素中的较大值,让较小的元素后移,与较大值看齐,便可找到两链表中值相同结点,插入A表,一个链表遍历结束后将剩余链表内存释放,尾插法需要尾指针以及最后尾结点置空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 LinkList Union (LinkList &A,LinkList &B) { if (A->next==NULL ||B->next==NULL ) return NULL ; LNOde *p=A->next,*q=B->next,*r=A; LNode *s; while (p!=NULL &&q!=NULL ){ if (p->data<q->data){ s=p->next; free (p); p=s; } else (p->data>q->data){ s=q->next; free (q); q=s; } else { r->next=p; r=p; p=p->next; s=q->next; free (q); q=s; } } while (p!=NULL ){ s=p->next; free (p); p=s; } while (q!=NULL ){ s=q->next; free (q); q=s; } r->next=NULL ; free (B); return A; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
20.两个递增有序单链表归并为一个非递减有序单链表
思路:(尾插法)同时遍历两表,找出遍历元素中的较小值,插入A表,一个链表遍历结束后将剩余链表插入A表,尾插法需要尾指针以及最后尾结点置空
题目:设A和B是两个带头结点的递增有序单链表,请设计一个算法,将A和B两个单链表归并为一个带头结点的非递减有序单链表,要求利用原来两个单链表的结点组成归并后的单链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 LinkList Merge (LinkList A,LinkList B) { if (A->next==NULL &&B->next==NULL ) return NULL ; LNode *p=A->next,*q=B->next,*r=A; while (p!=NULL &&q!=NULL ){ if (p->data<=q->data){ r->next=p; r=p; p=p->next; } else { r->next=q; r=q; q=q->next; } } while (p!=NULL ){ r->next=p; r=p; p=p->next; } while (q!=NULL ){ r->next=q; r=q; q=q->next; } r->next=NULL ; free (B); return A; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
21.两个递增有序单链表归并为一个非递增有序单链表
题目:设A和B是两个带头结点的递增有序单链表,请设计一个算法,将A和B两个单链表归并为一个带头结点的非递增有序单链表,要求利用原来两个单链表的结点组成归并后的单链表
思路:(头插法)同时遍历两表,找出遍历元素中的较小值,插入A表,一个链表遍历结束后将剩余链表插入A表,头插法注意防断链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 LinkList Merge (LinkList A,LinkList B) { if (A->next==NULL &&B->next==NULL ) return NULL ; LNode *p=A->next,*q=B->next,*r; A->next=NULL ; while (p!=NULL &&q!=NULL ){ if (p->data<=q->data){ r=p->next; p->next=A->next; A->next=p; p=r; } else { r=q=->next; q->next=A->next; A->next=q; q=r; } } while (p!=NULL ){ r=p->next; p->next=A->next; A->next=p; p=r; } while (q!=NULL ){ r=q->next; q->next=A->next; A->next=q; q=r; } frer(B); return A; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
22.两个递增有序单链表求差集
思路:同时遍历两表,A表较小则插入,B表较小则释放内存,相等则同时释放,一个链表结束遍历后,A表剩余则插入,B表剩余则释放,尾插法需要尾指针以及最后尾结点置空
题目:设A和B是两个带头结点的递增有序单链表,请设计一个算法,求单链表A与B的差集,并返回差集链表。链表A与B的差集定义为:在链表A中存在但不在链表B中存在的所有结点的集合。要求利用原来两个单链表的结点组成差集链表,其它结点均释放其空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 LinkList Diff (LinkList A,LinkList B) { if (A->next==NULL ||B->next==NULL ) return NULL ; LNode *p=A->next,*q=B->next,*r=A; LNode *s; while (p!=NULL &&q!=NULL ){ if (p->data<q->data){ r->next=p; r=p; p=p->next; } else if (p->data>q->data){ s=q->next; free (q); q=s; } else { s=p->next; free (p); p=s; s=q->next; free (q); q=s; } } while (p!=NULL ){ r->next=p; r=p; p=p->next; } while (q!=NULL ){ s=q->next; free (q); q=s; } r->next=NULL ; free (B); return A; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
23.判断序列B是否为序列A的连续子序列
题目:两个整数序列 A={a1,a2,a3,…,am}和 B={b1,b2,b3,…,bn}已经存入两个带头 结点的单链表中。请设计一个算法,判断序列B是否是序列A的连续子序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 bool Pattern (LinkList A,LinkList B) { LNode *p=A->next,*q=B->next; LNode *pre=A->next; while (p!=NULL &&q!=NULL ){ if (p->data==q->data){ p=p->next; q=q->next; } else { pre=pre->next; p=pre; q=B->next; } } if (q==NULL ) return true ; else return false ; }时间复杂度和空间复杂度分别为:O(mn)和O(1 )
24.判断单链表是否有环
题目:通常单链表尾结点指针域为 NULL,而单链表有环,是指单链表最后一 个结点的指针指向了链表中的某个结点。请设计一个算法,判断一个带头结点的 单链表 L 是否有环,如果有环,返回环的入口结点位置,如果没有,返回 NULL。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 LNode *FindLoop (LinkList L) { if (L->next=NULL ) return NULL ; LNode *fast=L,*slow=L; while (fast!=NULL &&fast->next!=NULL ){ slow=slow->next; fast=fast->next->next; if (fast==slow) break ; } if (fast==NULL ||fast->next==NULL ) return NULL ; LNode *p=L,*q=slow; while (p!=q){ p=p->next; q=q->next; } return p; } 时间复杂度和空间复杂度分别为:O(n)和O(1 )
25.将一个循环单链表链接到另一个循环单链表之后
题目:有两个带头结点的非空循环单链表 h1 和 h2,请设计一个算法,将链表 h2 链接到链表 h1 之后,要求链接后的链表仍是一个带头结点的循环单链表。
1 2 3 4 5 6 7 8 9 10 11 LinkList Link (LinkList h1,LinkList h2) { LNode *p=h1,*q=h2; while (p->next!=h1) p=p->next; while (q->next!=h2) q=q->next; p->next=h2->next; q->next=h1; free (h2); h2 的头结点 return h1; }时间复杂度和空间复杂度分别为:O(m+n)和O(1 )
26.一个循环单链表按结点值类型分解为三个循环单链表
题目:有一个带头结点的循环单链表L,链表L中含有三类字符的数据元素(如: 字母字符、数字字符和其它字符),请设计一个算法,将链表 L 拆分为三个带头 结点的循环单链表,其中每个循环单链表均只含一类字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 void Split (LinkList L,LinkList &A,LinkList &B,LinkList &C) { if (L->next=NULL ;) return 0 ; A=(LinkList)malloc (sizeof (LNode)); B=(LinkList)malloc (sizeof (LNode)); C=(LinkList)malloc (sizeof (LNode)); LNode *p=L->next,*ra=A,*rb=B,*rc=C; while (p!=L){ if ((p->data>='A' &&p->data<='Z' )||(p->data>='a' &&p->data<='z' )){ ra->next=p; p=p->next; } else if (p->data>='0' &&p->data<='9' ){ rb->next=p; rb=p; } else { rc->next=p; rc=p; } p=p->next; } ra->next=A; rb->next=B; rc->next=C; free (L); }
27.删除不带头结点单链表中的最小值结点
题目:有一个不带头结点的单链表 L,L 中各个结点的值都不相同,请设计一 个算法,删除链表 L 中的最小值结点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 void Del_Min (LinkList &L) { if (L==NULL ) return ; LNode *pre,*p=L; LNode *minpre,*minp=p; while (p!=NULL ){ if (p->data<minp->data){ minp=p; minpre=pre; } pre=p; p=p->next; } if (minp==L){ L=L->next; free (L); } else { minpre->next=pre->next; free (minp); } }
方法二(先自行创建头结点,完成题目要求后再删除所创建的头结点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void Del_Min (LinkList &L) { if (L==NULL ) return ; LinkList head=(LinkList)malloc (sizeof (LNode)); head->next=L; LNode *pre,*p=L; LNode *minpre,*minp=p; while (p!=NULL ){ if (p->data<minp->data){ minp=p; minpre-=pre; } pre=p; p=p->next; } minpre->next=minp->next; free (minp); L=head->next; free (head); }
28.不带头结点单链表循环右移k个位置
题目:设将n(n>1)个整数存放到不带头结点的单链表L中,设计算法将L中保存的序列循环右移k(0<k<n)个位置。例如,若k=1,则将链表{0,1,2,3}变为 {3,0,1,2}
1 2 3 4 5 6 7 8 9 10 11 12 13 void Move_k (LinkList &L,int k) { LNode *p=L; int len=1 ; while (p->next!=NULL ){ p=p->next; len++; } p->next=L; for (int i=0 ;i<len-k;i++) p=p->next; L=p->next; p->next=NULL ; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
29.计算不带头结点单链表的最大孪生和
题目:设有一个不带头结点的长度为n(n为偶数)的非空单链表,且结点值都大于0,设计算法求这个单链表的最大孪生和。孪生和定义为一个结点值与其孪生结点值之和,对于第i个结点(从0开始),其孪生结点为第n-i-1个结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int MaxSum (LinkList L) { LNode *slow=L,*fast=L->next; while (fast!=NULL &&fast->next!=NULL ){ slow=slow->next; fast=fast->next->next; } LNode *p=slow->next,*q; slow->next=NULL ; while (p!=NULL ){ q=p->next; p->next=slow->next; slow->next=p; p=q; } p=L,q=slow->next; int max=p->data+q->data; while (q!=NULL ){ if ((p->data+q->data)<max) max=p->data+q->data; p=p->next; q=q->next; } return max; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
30.约瑟夫环
题目:(约瑟夫环)有n个人围成一个圈,他们的编号为1~n。现在要求从第1个人开始报数,数到m的人出列,出列后的下一个人继续从1开始报数,同样数到m的人出列,一直重复此过程,直到圈中只剩下最后一个人,返回其编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int Josephus (LinkList L,int m) { LNode *p=L,*pre=L; while (pre->next!=L) pre=pre->next; while (p->next!=p){ for (int i=1 ;i<m;i++){ pre=p; p=p->next; } pre->next=p->next; free (p); p=pre->next; } return p->data; }时间复杂度和空间复杂度分别为:O(mn)和O(n)
31.双链表的结构体定义
1 2 3 4 typedef struct DNode { int data; struct DNode *prior ,*next ; }DNode,*DLinkList;
32.有序双链表插入一个新结点后依然有序
题目:在一个带头结点的非递减有序双链表中插入一个值为 x 的新结点,使得 插入新结点后链表依然非递减有序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 viod LintInsert (DLinkList L,int x) { DNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data>x) break ; pre=p; p=p->next; } DNode *s=(DLinkList)malloc (sizeof (DNode)); s->data=x; s->next=pre->next; if (p->next!=NULL ) pre->next->prior=s; s->prior=pre; pre->next=s; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
33.删除双链表中的最小值结点
题目:有一个带头结点的双链表 L,L 中各个结点的值都不相同,请设计一个 算法,删除链表 L 中的最小值结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void Del_Min (DLinkList L) { if (L->next==NULL ) return ; DNode *minpre=L,*minp=L->next; DNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data<minp->data){ minp=p; minpre=pre; } pre=p; p=p->next; } minpre->next=minp->next; if (minp->next!=NULL ) minp->next->prior=minpre; free (minp); }时间复杂度和空间复杂度分别为:O(n)和O(1 )
34.判断循环双链表是否对称
题目:请设计一个算法,判断带头结点的循环双链表 L 是否对称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 bool Symmetry (DLinkList L) { if (L->next==L||L->next->next==L) return true ; DNode *p=L->next,*q=L->prior; while (p!=q&&p->next!=q){ if (p->data==q->data){ p=p->next; q=q->prior; } else return false ; } return true ; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
35.将双链表中的最大值结点移动到最前面
题目:有一个带头结点的双链表 L,L 中各个结点的值都不相同,请设计一个算法,将链表 L 中的最大值结点移动到最前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void Move_Max (DLinkList L) { if (L->next==NULL ) return ; DNode *maxpre=L,*maxp=L->next; DNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data>maxp->data){ maxp=p; maxpre=pre; } } if (maxp==L->next) return ; DNode *q=maxp->next; maxpre->next=q;/前驱结点的后继指针指向后继结点 if (q!=NULL ) q->prior=maxpre; q=L->next; maxp->next=q; q->prior=maxp; L->next=maxp; maxp->prior=L; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
36.双链表中结点按查找频度递减顺序排列
题目:设有一个带头结点的非循环双链表 L,其每个结点除了有 prior、data 和 next 域外,还有一个访问频度域 freq,其值均初始化为 0。L中各个结点的值都 不相同,每当在链表中执行一次 Locate(L,x)运算时,令值为 x 的结点中 freq 域的值增 1,并使此链表中的结点保持按访问频度递减的顺序排列,且最近访问的结 点排在频度相同的结点之前,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的 Locate(L,x)函数,返回找到结点的地址,类型为指针型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 DNode *Locate (DLinkList L,int x) { if (L->next==NULL ) return NULL ; DNode *pre=L,*p=L->next; while (p!=NULL ){ if (p->data==x) break ; pre=p; p=p->next; } if (p==NULL ) return NULL ; p->freq++; if (p->prior==L) return p; DNode *q=p->next; pre->next=q; if (q!=NULL ) q->prior=pre; pre=L,q=L->next; while (q!=NULL ){ if (q->freq<p->freq) break ; pre=q; q=q->next; } p->next=q; q->prior=p; p->prior=pre; pre->next=p; return p; }时间复杂度和空间复杂度分别为:O(n)和O(1 )
37.递归查找不带头结点单链表中的最小值结点
题目:有一个不带头结点的单链表 L,L 中各个结点的值都不相同,请设计一个递归算法,查找链表 L 中的最小值结点
1 2 3 4 5 6 7 8 9 LNode *Find_Min (LinkList L) { if (L==NULL ||L->next=NULL ) return L; LNode *p=Find_Min(L->next); if (p->data<L->data) return p; else return L; }时间复杂度和空间复杂度分别为:O(n)和O(n)