1. 程式人生 > >顛倒一個鏈表的順序 C++

顛倒一個鏈表的順序 C++

下一個 解讀 創建 們的 完成 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++