單鏈表逆序三種方法


准備

定義結構體

typedef struct Node{ int data; struct Node* next; }Node,*pNode;

鏈表初始化

void initHead(pNode &head){ head=new Node; head->next=NULL; }

鏈表建立(尾插法)

void bulidHead(pNode &head){ pNode tail=head; tail->next=NULL; for(int i=0;i<10;i++){ //將0~9插入鏈表 pNode p=new Node; p->data=i; tail->next=p; tail=p; tail->next=NULL; } }

鏈表打印

void printHead(pNode &head){ pNode p=head->next; while(p){ cout<<p->data<<" "; p=p->next; } }

鏈表銷毀

void destroyHead(pNode &head){ pNode p=head; while(head){ p=head->next; delete head; head=p; } }

 

一、迭代法

 

                                   

                                  

需要三個指針,前驅p1,當前p2,后繼p3

結束的條件是p2==null

帶頭節點

void reverse1(pNode &head){ if(head->next!=NULL&&head->next->next!=NULL){  //至少有除頭節點以外兩個節點才能逆序 pNode p1=head->next,p2=head->next->next,p3=NULL; while(p2){ p3=p2->next; p2->next=p1; if(p1==head->next) {    //放在出現環,可以這樣寫是因為環只可能
                p1->next=NULL;      //出現在第一個和第二個節點之間。要把循環去掉,否則打印時會出現死循環
 } p1=p2; p2=p3; } head->next=p1; } //head變成新頭節點返回 
    else return; }

不帶頭結點 

 

pNode reverse1(pNode head){ if(head!=NULL&&head->next!=NULL){         //至少有除頭節點以外兩個節點才能逆序
        pNode p1=head-,p2=head->next,p3=NULL; while(p2){ p3=p2->next; p2->next=p1; if(p1==head) {    //放在出現環,可以這樣寫是因為環只可能
                p1->next=NULL;      //出現在第一個和第二個節點之間。要把循環去掉,否則打印時會出現死循環
 } p1=p2; p2=p3; } return p1; } //head變成新頭節點返回 
    else return head; }

 

 

 

加深理解:

https://blog.csdn.net/bjweimengshu/article/details/87128224?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control

https://www.bilibili.com/video/BV1Y64y1c7YJ?from=search&seid=3296478633528350640

二、插入法

 

不會出現上面的環,並且head和p1都不會改變,只需要改變p2,p3即可。

void reverse2(pNode &head){ if(head->next!=NULL&&head->next->next!=NULL){  //至少有兩個節點 pNode p1=head->next,p2=head->next->next,p3=NULL; while(p2){ p3=p2->next; //插入順序從后往前 p1->next=p3; p2->next=head->next; //注意用head->next head->next=p2; p2=p3; } } else return; }

加深理解:https://www.bilibili.com/video/BV1Y64y1c7YJfrom=search&seid=3296478633528350640

三、遞歸

采用遞歸的方式,如果要將當前結點逆序,那么先將它的后繼結點都逆序,然后把逆序后的尾結點的next指向當前結點即可,要注意的是遞歸出口,我們選擇鏈表為空或者只有一個結點的情況為遞歸出口。

第一次遞歸調用:

 

頭節點head的下一個節點head->next將是逆序后的新鏈表的尾節點,也就是說,被摘除的頭接點head需要被連接到head->next才能完成整個鏈表的逆序

第二次遞歸:

 

再進行一次遞歸:

 

遞歸終止條件就是鏈表只剩一個節點時直接返回這個節點的指針。可以看出這個算法的核心其實是在回朔部分,遞歸的目的是遍歷到鏈表的尾節點,然后通過逐級回朔將節點的next指針翻轉過來。

不帶頭結點

pNode reverse3_no_head(pNode head){ if(head==NULL||head->next==NULL){ return head; } else { pNode newHead = reverse3_no_head(head->next); //遞歸部分 head->next->next = head; //回溯部分 head->next = NULL; return newHead; } }

帶頭節點

void reverse3_with_head(pNode &head){ if (head == NULL){ return; } pNode newHead = reverse3_no_head(head->next); //結合不帶頭結點的遞歸 head->next = newHead; }

加深理解:

https://www.bilibili.com/video/BV13r4y1T7yY/?spm_id_from=333.788.recommend_more_video.-1

全部代碼

#include<iostream>
using namespace std; typedef struct Node{ int data; struct Node* next; }Node,*pNode; void initHead(pNode &head){ head=new Node; head->next=NULL; } void bulidHead(pNode &head){ pNode tail=head; tail->next=NULL; for(int i=0;i<10;i++){ pNode p=new Node; p->data=i; tail->next=p; tail=p; tail->next=NULL; } } void printHead(pNode head){ pNode p=head->next; while(p){ cout<<p->data<<" "; p=p->next; } } void destroyHead(pNode &head){ pNode p=head; while(head){ p=head->next; delete head; head=p; } } pNode reverse(pNode head){ if(head==NULL||head->next==NULL) return head; pNode n=reverse(head->next); head->next->next=head; head->next=NULL; return n; } void reverse1(pNode &head){ if(head->next!=NULL&&head->next->next!=NULL){ pNode p1=head->next,p2=head->next->next,p3=NULL; while(p2){ p3=p2->next; p2->next=p1; if(p1==head->next) {    //放在出現環,可以這樣寫是因為環只可能
                p1->next=NULL;      //出現在第一個和第二個節點之間
 } p1=p2; p2=p3; } head->next=p1; } //head變成新頭節點返回 
    else return; } void reverse2(pNode &head){ if(head->next!=NULL&&head->next->next!=NULL){ pNode p1=head->next,p2=head->next->next,p3=NULL; while(p2){ p3=p2->next; p1->next=p3; p2->next=head->next; head->next=p2; p2=p3; } } else return; } pNode reverse3_no_head(pNode head){ if(head==NULL||head->next==NULL){ return head; } else { pNode newHead = reverse3_no_head(head->next); head->next->next = head; head->next = NULL; return newHead; } } void reverse3_with_head(pNode &head){ if (head == NULL){ return; } //pNode firstNode = head->next;
    pNode newHead = reverse3_no_head(head->next); head->next = newHead; } int main(){ pNode head=NULL; initHead(head); bulidHead(head); printHead(head); cout<<endl; reverse3_with_head(head); printHead(head); destroyHead(head); return 0; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM