综合应用
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)。为达到最佳的性能,可以先提取出数据到数组,进行快速排序,时间复杂度达到最小。