Problem1:/*设计递归算法,删除不带头结点的单链表L中的值为x的结*/
void solve1(LNode *L,x){
LNode *p=NULL;
if(L==NULL)
return 0;
if(L->data==x){
p=L;
L=L-next;
free(p);
solve1(L,x);
}
else{
solve1(L->next,x);
}
}
Problem2:/*在带头结点的单链表中,删除所有值为x的结点,并释放其空间*/
Solution:/*用p遍历链表,pre始终指向p的前驱节点,若与x相等,则删除*/
void solve2(LNode *L){
LNode *p=L->next;
LNode *pre=L,q=NULL;
while(p!=NULL){
if(p->data==x){
q=p;
p=p->next;
pre->next=p;
free(q);
}
else{
pre=p;
p=p->next;
}
}
}
Problem3:/*设L为带头结点的单链表,编写算法实现从尾到头反向输出结点值*/
Solution1:/*采用递归方式访问链表结点,当访问完最后一个结点时再开始输出*/
solve3(LNode *L){
if(L->next!=NULL){
solve10(L->next);
}
if(L!=NULL)
print(L->data);
}
Solution2:/*采用栈的方法,先让结点入栈,再出栈,便可颠倒输出顺序*/
void solve3(LNode *L){
LNode *p=L->next;
LNode *stack[max]={NULL}:
LNode *q=NULL;
int top=-1;
while(p!=NULL){
stack[++top]=p;
p=p->next;
}
while(top>-1){
q=stack[top--];
print(q->data);
}
}
Problem4:/*在带头结点的单链表中,删除值最小的结点*/
void solve4(LNode *L){
LNode *p=L->next;
LNode *pre=L;
LNode *minpre=pre;
int min=INFMax;
while(p!=NULL){
if(p->data<min){
min=p->data;
minpre=pre;
}
pre=p;
p=p->next;
}
}
Problem5:/*将带头结点的单链表就地逆置,即要求辅助空间复杂度为O(1)*/
Solution:/*先将头结点摘下,再将头结点后面的元素头插到头结点上*/
void solve5(LNode *L){
LNode *p=L->next;
LNode *q=NULL;
L->next=NULL;
while(p!=NULL){
r=p;
p=p->next;
r->next=L->next;
L->next=r;
}
}
Problem6:/*对于一个带头结点的单链表L,设计一个算法使其元素递增有序*/
Solution:/*采用直接插入排序法,先保留头结点及其后面的一个结点构成初始的有序单链表
,然后用指针p遍历剩余的无序链表,再依次将无序链表中的结点插到有序链表中的
合适位置,直到无序链表中不再有结点为止*/
void solve6(LNode *L){
LNode *p=L->next->next;
LNode *pre;
L->next->next=NULL;
while(p!=NULL){
r=p-next;
pre=L;//每次都从有序链表的第一个结点开始,从前往后比较
while(pre!=NULL&&p->data>pre->next->data)
pre=pre->next;
p->next=pre->next;
pre->next=pre;
p=r;
}
}
Problem7:/*给定一个带头结点的单链表,结点元素为整型,要求按递增顺序输出
结点元素,并释放结点所占存储空间*/
Solution:/*用指针p遍历链表,每次都从头开始遍历,每遍历完一轮,就找出该轮
中值最小的结点,然后输出,并释放该节点所占空间,重复上述步骤,直到链表为
空时结束。minp指向最小结点,minpre指向其前驱结点*/
void solve7(LNode *L){
LNode *p,*pre;
LNode *minp,*minpre;
while(L->next!=NULL){
pre=L;
p=L->next;
minp=p;
minpre=pre;//之前漏了这一步
while(p!=NULL){
if(p->data<minp->data){
minp=p;
minpre=pre;
}
else{
pre=p;
p=p->next;
}
}
printf("%d\t",minp->data);
minpre->next=minp->next;
free(minp);
}
free(L);
}
Problem8:/*有一个递增有序的单链表,要求删除其重复元素,只保留每个重复元素中的一个即可*/
Solution:/*因为链表已经是递增有序的,所以重复的元素一定是相邻的*/
void solve8(LNode *L){
LNode *p=L->next;
LNode *q;
while(p!=NULL){
q=p->next;
if(q->data==p->data){
p->next=q->next;//这里是p->next在移动
free(q);
}
else{
p=p->next;
}
}
}
Problem9:/*设A,B是两个递增有序的单链表,要求找他们的公共元素,然后插在
但链表C的后面,不破坏A,B链表*/
Solution:/*依次比较A,B的元素,若不相等,则让值小的指针往后移,若值相等,则
将该结点尾插到C链表后面,然后再让两个指针一起后移*.重复上述过程,直到其中
一个链表先遍历完就停止*/
LNode *solve9(LNode *A,LNode *B){
LNode *p=A->next;
LNode *q=B->next;
LNode *C,*r,*s;
C=(LNode *)malloc(sizeof(LNode));
r=C;
while(p!=NULL&q!=NULL){
if(p->data<q->data)
p=p->next;
if(q->data<p->data)
q=q->next;
if(q->data==p->data){
s=(LNode *)malloc(sizeof(int));
s->data=p->data;
r->next=s;
r=s;
p=p->next;
q=q->next;
}
}
r->next=NULL;
return C;
}
Problem10:/*设单链表L=(a1,a2,a3,...,an-1,an),重新排列,使其变为
L'=(a1,an,a2,an-1,a3,...)*/
Solution:/*L'是由L先挑第一个元素,再挑倒数第一个元素依次合并成的,
step1:先找中间结点,为此设置两个指针p,q。p每走一步,q就走两步,当
q走到链尾时,p便走到链表中间;
step2:再将链表L后半段的元素原地逆置;
step3:*/
void solve10(LNode *L){
LNode *p=L->next;
LNode *q=L->next;
LNode *q,*r;
while(q->next!=NULL){
p=p->next;
q=q->next;
if(q->next!=NULL)
q=q->next;
}
q=p->next;//此处P已经位于链表的中点
p->next=NULL;//暂时将链表前后切分
while(q!=NULL){//逆置链表后半段
r=q->next;//先保存q的下一个结点
q->next=p->next;
p->next=q;
q=r;//更新q
}
s=L->next;
q=p->next;
while(q!=NULL){
r=q->next;
q->next=s->next;
s->next=q;
s=q->next;//s是变化的,每次新插入到结点都接到s后面
q=r;
}
}
王道代码练习-(链表)
最新推荐文章于 2023-09-14 11:53:30 发布