链表习题(一)
综合应用
1.设计一个递归算法,删除不带头节点的单链表L中的所有值为x的节点。
递归模型:
终止条件:f(L,x)=不做任何事情 若L为空表
递归主体:f(L,x)=删除*L结点;f(L->next,x); 若L->data==x
其他情况:f(L,x)=f(L->next,x); 其他情况
void Del_X_3(Linklist &L,ElemType x){
LNode *p;
if(L==NULL)
return;
if(L->data==x){
p=L;
L=L->next;
free(p);
Del_X_3(L,x);
}
else
Del_X_3(L->next,x);
}
2.非递归实现1问
void Del_X_3(Linklist &L,ElemType x){ LNode *p=L->next,*pre=L,*q; while(p!=NULL){ if(p->data=x){ q=p; p=p->next; pre->next=p; free(q); } else{ pre=p; p=p->next;} } }
3.设L为带头结点的单链表,编写算法实现从尾到头的反向输出每个结点的值
可以用递归或者栈的思想解决。
void P_print(Linklist L){ if(L-next!=NULL){ R_print(L->next);} if(L!=NULL) print(L->data); }
4.试编写在带头结点的单链表L中删除一个最小值结点的高效算法
Linklist Delete_Min(Linklist &L){ LNode *pre=L,*p=pre->next; LNode *minpre=pre,*minp=p; while(p!=NULL){ if(p->data<minp->data){ minp=p; minpre=pre; } pre=p; p=p->next; } minpre->next=p->next; free(minp); return L; }
5.试编写算法将带头结点的单链表就地逆置,指辅助空间复杂度为O(1)。
可以采用头插法。时间复杂度为(n),空间复杂度为(1)。
法一:
Linklist Reverse(Linklist L){
LNode *p,*r;
p=L->next;
L-Next=NULL:
while(p!+NULL){
r=p->next;
p->next=L->next;
L->next=p;
p=r;
}
return L;
}
法二:
直接原地调整指针指向
Linklist Reverse(Linklist L){
LNode *pre,*p=L->next,*r=p->next;
p->next=NULL:
while(r!=NULL){
pre=p;
p=r;
r=r->next;
p->next=pre;
}
L->next=p;
return L;
}
6.有一个带头结点的单链表L,设计一个算法使其元素递增有序
采用直接插入排序算法思想
void Sort(Linklist &L){
LNode *p=L->next,*pre;
LNode *r=p->next;
p->next=NULL;
p=r;
while(p!=NULL)
{
r=p->next;
pre=L;
while(L->next!=NULL&&L->next->data<p->data)
pre=pre->next;
p->next=pre->next;
pre->next=p;
p=r;
}
}
时间复杂度为(n^2)。为达到最佳的性能,可以先提取出数据到数组,进行快速排序,时间复杂度达到最小。