顛倒一個鏈表的順序 C++
阿新 • • 發佈:2017-12-04
下一個 解讀 創建 們的 完成 truct eve clu 逆序
首先我們定義一個頭結點:
struct Node{ int data; Node*next; };
接下來我們寫一個函數來創建一個鏈表:
//a是一個數組,n代表數組元素的個數 Node*createLinkList(int a[],int n) { if(a==NULL||n==0) return NULL; Node*L,*T=NULL; for(int i=0;i<n;i++) { if(i==0) {L=new Node; L->data=a[i]; L->next=NULL; T=L; }else { Node*s=new Node; s->data=a[i]; s->next=NULL; T->next=s; T=s;//結點移動 } } return L; }
下面就開始我們的翻轉方法部分
1)首先我們先用遞歸方法來進行處理
(1)如果一個鏈表為空鏈表,那麽他的逆序還是為空
(2)如果一個鏈表中只有一個節點,那麽他的逆序就是這個鏈表本身.
(3)如果一個鏈表的長度大於一,那麽我們做如下遞歸.
把當前鏈表的除了頭節點L之外的剩余節點組成的鏈表逆序,也就是遞歸調用,並得到剩余鏈表逆序後的頭結點p,
此時將L的下一個節點的的next指向L, 並將L的next指針置空.然後返回p.
(簡單來說,先是一層層尋找,找到尾結點返回給p,然後返回上一層,這時最後一個節點為L->next,將L->next的next指向現在第二層的L,然後再把L的next置空,即完成了第一次翻轉,然後再返回給p;把這次的兩個結點看成最後一個,然後在倒數第三層重復反轉,最後完成整個反轉)
Node*reverseLinkList(Node*L) { if(L==NULL) return NULL; if(L->next==NULL) return L; Node*p=reverseLinkList(L->next); L->next->next=L;//倒數第一個指向倒數第二個 L->next=NULL;//倒數第二個指針置空 return p; }
2)第二種方法就不進行遞歸進行翻轉,然而我們直接在最後翻轉會出現斷鏈,進而不能進行連續遍歷,所以我們可以定義三個結點,pnow指向當前結點,pre指向它的前置,nex指向它的後驅,首先令pnow的下一個指針指向nex,然後令pnow的next拆掉並連接pre,進行翻轉,這時pnow和nex之間是斷開的,然後將pnow設置為前驅pre,將nex設置為pnow,即完成了一段翻轉,重復到完畢即可。
Node*noreverseLinkList(Node*L) { if(L==NULL||L->next==NULL) return L; Node*pnow=L,*pre=NULL,*nex=NULL,*tail=NULL; while(pnow!=NULL) { nex=pnow->next; if(NULL==nex){ tail=pnow;} pnow->next=pre; pre=pnow; pnow=nex; } return tail; }
為了驗證,我們還要寫一個顯示函數:
void display(Node*L) { Node*p=L; if(p==NULL) return ; while(p!=NULL) { cout<<p->data<<" "; p=p->next; } cout<<endl; }
完整代碼:
include<iostream> using namespace std; struct Node{ int data; Node*next; }; //a是一個數組,n代表數組元素的個數 Node*createLinkList(int a[],int n) { if(a==NULL||n==0) return NULL; Node*L,*T=NULL; for(int i=0;i<n;i++) { if(i==0) {L=new Node; L->data=a[i]; L->next=NULL; T=L; }else { Node*s=new Node; s->data=a[i]; s->next=NULL; T->next=s; T=s;//結點移動 } } return L; } void display(Node*L) { Node*p=L; if(p==NULL) return ; while(p!=NULL) { cout<<p->data<<" "; p=p->next; } cout<<endl; } Node*reverseLinkList(Node*L) { if(L==NULL) return NULL; if(L->next==NULL) return L; Node*p=reverseLinkList(L->next); L->next->next=L;//倒數第一個指向倒數第二個 L->next=NULL;//倒數第二個指針置空 return p; } Node*noreverseLinkList(Node*L) { if(L==NULL||L->next==NULL) return L; Node*pnow=L,*pre=NULL,*nex=NULL,*tail=NULL; while(pnow!=NULL) { nex=pnow->next; if(NULL==nex){ tail=pnow;} pnow->next=pre; pre=pnow; pnow=nex; } return tail; } int _tmain(int argc, _TCHAR* argv[]) { int a[] = {1,2,3,4,5,6}; int b[] = {1,2,3,4,5,6,7}; Node *L = createLinkList(a,6); display(L); display(noreverseLinkList(L)); Node *A = createLinkList(b,7); display(reverseLinkList(A)); system("pause"); return 0; }
謝謝閱讀。詳細解讀:(有圖理解)http://blog.csdn.net/zhaoruixiang1111/article/details/49932603
顛倒一個鏈表的順序 C++