Blog Details

Home世界杯在哪里举办单链表逆序三种方法

单链表逆序三种方法

准备

定义结构体

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<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

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<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<

reverse3_with_head(head);

printHead(head);

destroyHead(head);

return 0;

}

Copyright © 2088 世界杯历史_2018世界杯亚洲区预选赛 - mcryt.com All Rights Reserved.
友情链接