反转链表四种方法

建议

最好先看代码,然后按照代码画图理解,还有问题可以看看b站视频看完还是得自己画画理解。(亲测有效)

建立链表

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node{
    int num;
    struct Node* next;
}Node;
//初始化
Node* Begin(){
    Node * head;
    head=(Node*)malloc(sizeof(Node));
    head->next=NULL;
    return head;
}
//建立,尾插法
void Creat(Node* head){
    Node*r,*s;
    int num;
    r=head;
    while(1){
        scanf("%d",&num);
        if(num){
            s=(Node*)malloc(sizeof(Node));
            s->num=num;
            r->next=s;
            r=s;
        }else break;
    }
    r->next=NULL;
}
//输出
void output(Node* head){
    Node*p;
    p=head->next;
    while(p){
        printf("%d ",p->num);
        p=p->next;
    }
}
int main(){
    Node*ha,*hb;
    ha=Begin();
    printf("请输入数字:\n");
    Creat(ha);
    //hb=Begin();
    //hb->next=reserve(ha);
    printf("您反转后的数字为: \n");
    reserve(ha);//选择hb后注释掉此行
    output(ha);//看方法选择hb
}

头插法

原理:在建立链表的时候使得输入的数据按输入先后倒序存入(即最先存储的最终在尾结点以此类推),注意并不是原地反转。
代码实现:

//头插法倒转
void creat(Node*head){
    Node*s,*r;
    int num;
    s->next=NULL;
    while(1){
        scanf("%d",&num);
        if(num==0)break;
        s=(Node*)malloc(sizeof(Node));
        s->num=num;
        s->next=head->next;
        head->next=s;
    }
}

类似头插法的原地反转

思路

  1. 引入p,q;
  2. 让p指向链表的首元结点
  3. q指向p的下一个
  4. 让头结点指向空,即原链表成了空表,(仍能通过p得到原来结点的数据 )
  5. 利用p,q依次取出原链表的每一个元素并插入到头结点的后面–>实现逆序

在这里插入图片描述
(呜呜呜孩子还不会用电脑画流程图,凑活看吧…)
在这里插入图片描述

代码实现

void reserve(Node*head){
    Node*p,*q;
    p=head->next;
    head->next=NULL;
    while(p){
        q=p->next;
        p->next=head->next;
        head->next=p;
        p=q;
    }
}

迭代法

思路

  1. 设置三个指针分别表示之前(pre),现在(cur),下一个(next)
  2. pre初始化为空,cur初始化为首元结点
  3. next指向cur的下一个;cur指向pre;pre跳到cur;cur跳到next…
  4. 重复3,直到cur为空,此时pre跳到了链表的尾结点,跳出循环 返回pre,
  5. 注意返回的pre不能直接做头结点因为他存数据了最好做首元结点
    在这里插入图片描述

代码实现

Node* reserve(Node*head){
    Node *cur,*pre,*Next;
    pre=NULL;
    cur=head->next;
    while(cur){
        Next=cur->next;
        cur->next=pre;
        pre=cur;
        cur=Next;  
    }
    return pre;
}

递归法

思路:

  1. 不断调用自身(通过传入参数head->next,类似形成叠加图层)直到找出尾结点(new);
  2. 让当前层的head的下一个结点指向head自己,再让自己指向空;
  3. 像:…–>a–>b变成…->a<–b;
  4. 最终返回new作为首元结点(new存放数据了);
    在这里插入图片描述
Node* reserve(Node*head){
    //printf("11");
    if(head->next==NULL){
        return head;
        //printf("dd");
    }
    else{    
        Node* new=reserve(head->next);
        //printf("pp");
        head->next->next=head;
        head->next=NULL;
        return new;
    }
}
//用这个方法得output中条件改一下while(p->next)

好耶!!!你会了四种方法!!!
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值