链表逆置的两种方法——头插法和就地逆置

初学数据结构,链表的操作除了增、删、改、查功能外,链表还有一项比较重要的操作——链表的逆置。于是对其进行了一番简单的研究。

首先,我们来创建一个链表(含头结点)

#include<stdio.h>                                                                                                                                        
#include<stdlib.h>

typedef struct node{
    int data;
    struct node *next;
}node;

node *creat(int n){
    node *head,*p,*q;
    int num;
    head = (node*)malloc(sizeof(node));
    head->next = NULL;
    q = head;
    while(n--){
        scanf("%d",&num);
        p = (node*)malloc(sizeof(node));
        p->data = num;
        q->next = p;
        q = p;
    }
    q->next = NULL;
    return head;
}

之后,介绍我们的第一种逆置方法:头插法

所谓头插法,就是使用一个结构体指针向后遍历,用另一个指针将前一个结点插入到头结点指向的下一个位置

//头插
void reverse_head(node *head){
    node *p,*q;
    p = head->next; //使用 p 依次向后遍历
    head->next = NULL;
    while(p){
        //前一负责指向插入结点的指针后移
        //在第二次 while 循环时看这个操作更清楚
        q = p;
        //向后遍历
        p = p->next;    
        //将 q 结点插入到头结点后面                                                                                                                          
        q->next = head->next;
        head->next = q;
    }
    return;
}


现在想想,这个命名也是十分恰当了。

第二种方法是:就地逆置法
与头插法十分类似,只不过是从是头结点后的第一个有效结点开始操作,完成后打印时,是从表尾开始打印

//就地逆置
//这里传入的是头结点的下一个有效结点
node *reverse_another(node *head){  
    if(head == NULL || head->next == NULL)  //判定返回
        return head;
    
    node *rev,*t,*cur;
    rev = NULL;
    cur = head;
    while(cur != NULL){
        //指针后移
        t = cur;
        //向后遍历
        cur = cur->next;
        //与头插法类似
        t->next = rev;
        rev = t;
    }
    return rev;
}   

下面是测试用的主函数

int main(){
    node *head;
    int n;
    printf("请输入数字个数:");
    scanf("%d",&n);
    head = creat(n);
    print(head);
    //头插输出
    reverse_head(head);             
    //就地逆置输出,注意传入的是头结点后的第一个有效结点
    //head->next = reverse_another(head->next); 
    print(head);
    return 0;
}   

本来是要自己画图,但是发现有大佬画的十分清楚的图,便引用一下(懒了):

感谢大佬!!!!!
图片来源:https://blog.csdn.net/qq_42322103/article/details/82668765

图解:
刚开始是这样:
在这里插入图片描述
循环前的操作
在这里插入图片描述
进入循环,分别用q和p记录第一个和第二个节点
在这里插入图片描述
在这里插入图片描述
进入第二轮循环,这是发生重大变化的关键时期
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这张图调整一下
在这里插入图片描述
直到链表为空

  • 9
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值