標籤:
有一個線性表$(a_1,a_2, \cdots, a_n)$, 採用帶頭結點的單鏈表$L$儲存,設計一個演算法將其就地逆置。所謂“就地”指輔助空間為$O(1)$。
解答:用$p$指標掃描原單鏈表,先將頭結點$L$的$next$域置為$NULL$而變成一個空鏈表,然後,將$*p$結點採用頭插法插入到$L$中。演算法如下:
1 void Reverse(LinkList *&L){ 2 LinkList *p=L->next,*q; 3 L->next=NULL; 4 while (p!=NULL) 5 { 6 q=p->next; 7 p->next=L->next; //將*p結點插入到建立鏈表的前面 8 L->next=p; 9 p=q;10 }11 12 }
上述演算法的圖示操作如下:
//完整代碼如下:
//LinkBase.h#include <stdio.h>#include <malloc.h>typedef int ElemType;typedef struct LNode{ ElemType data; struct LNode *next;}LinkList;void InitList(LinkList *&L){ L=(LinkList *)malloc(sizeof(LinkList)); L->next=NULL;}void DestroyList(LinkList *&L){ LinkList *p=L, *q=p->next; while(q!=NULL){ free(p); p=q; q=p->next; } free(p); }int ListLength(LinkList *L){ LinkList *p=L; int i=0; while(p->next!=NULL){ i++; p=p->next; } return i;}void DispList(LinkList *L){ LinkList *p=L->next; while(p!=NULL){ printf("%d ",p->data); p=p->next; } printf("\n");}int GetElem(LinkList *L,int i,ElemType &e){ int j=0; LinkList *p=L; while(j<i && p!=NULL){ j++; p=p->next; } if (p==NULL) { return 0; } else{ e=p->data; return 1; }}int LocateElem(LinkList *L,ElemType e){ LinkList *p=L->next; int n=1; while (p!=NULL && p->data!=e) { p=p->next; n++; } if(p==NULL) return 0; else return n;}int ListInsert(LinkList *&L,int i,ElemType e){ int j=0; LinkList *p=L,*s; while (j<i-1 && p!=NULL) { j++; p=p->next; } if(p==NULL) return 0; else{ s=(LinkList *)malloc(sizeof(LinkList)); s->data=e; s->next=p->next; p->next=s; return 1; }}int ListDelete(LinkList *&L,int i,ElemType &e){ int j=0; LinkList *p=L,*q; while (j<i-1 && p!=NULL) { j++; p=p->next; } if(p==NULL) return 0; else{ q=p->next; if(q==NULL) return 0; e=q->data; p->next=q->next; free(q); return 1; }}//主函數.cpp#include "LinkBase.h"#include <stdio.h>void Reverse(LinkList *&L){ LinkList *p=L->next,*q; L->next=NULL; while (p!=NULL) { q=p->next; p->next=L->next; //將*p結點插入到建立鏈表的前面 L->next=p; p=q; }}void main(){ LinkList *Ls = (LinkList *)malloc(sizeof(LinkList)); Ls->next=NULL; int i=0; for (i=1;i<10;i++) { ListInsert(Ls,i,i*i-1); } printf("原線性表:\n"); DispList(Ls); //ListInsert(Ls,3,15); Reverse(Ls); printf("反轉後的線性表:\n"); DispList(Ls); free(Ls);}
效果如下:
單鏈表反轉的圖示操作