图解链表倒置

链表倒置是一个经常遇到的问题,下面将用图示的方式讲述链表倒置的过程。

假设链表的长度为4,头指针head指向第一个节点。另外还有两个非常重要的指针,prev:带领head指针往下走,是个领航员,worker:位于head之后,为指针变换服务。最后返回的结果是一个head指针,指向的是一个已经倒置的链表。

1. 初始化:

Node *prev = null;
Node *worker = null;

2. 开始工作

prev = head.next;
worker = head;

 

 

3.  准备第一次指针变换

head = prev;
prev = head.next;

4. 变换指针

head.next = worker;
worker.next = null;

 

5. 准备第二次变换

worker = head;
head = prev;
prev = head.next;

 

6. 第二次指针变换

head.next = worker;

 

7. 准备第三次变换

worker = head;
head = prev;

 

8. 第三次变换

head.next = worker;

 

至此,已经变换完成。在一步步的代码中发现了一丝重复了吗?

让我们把之前每一步的代码都合在一起:

Node *prev = null;
Node *worker = null;
prev = head.next;
worker = head;
head = prev;
prev = head.next;
head.next = worker;
worker.next = null;
worker = head;
head = prev;
prev = head.next;
head.next = worker;
worker = head;
head = prev;
head.next = worker;

试着在第三行,第八行,第十二行之后,加一个空行。像这样:

Node *prev = null;
Node *worker = null;
prev = head.next;

worker = head;
head = prev;
prev = head.next;
head.next = worker;
worker.next = null;

worker = head;
head = prev;
prev = head.next;
head.next = worker;

worker = head;
head = prev;
head.next = worker;

现在我们将第一个节点的next域置为空的操作换种说法,也即是,在第四行上加上head.next = null,并删除第9行中的work.next=null,效果都是将第一个节点的next置为null; 之后,将最后一次的过程也改一下,在倒数第二行加上一句 prev = head.next;因为此时head已经指向最后一个节点,head.next = null, 也即 prev = null;

改造之后的代码为:

Node *prev = null;
Node *worker = null;
prev = head.next;
head.next = null;

worker = head;
head = prev;
prev = head.next;
head.next = worker;


worker = head;
head = prev;
prev = head.next;
head.next = worker;

worker = head;
head = prev;
prev = head.next;
head.next = worker;

嗯,现在非常清晰了。在加上判断条件吧,就以最后一次的操作为截至,此时,三个指针的值为:

prev = null
head = 最后一个节点
worker = 倒数第二个节点

最后以 prev是否为null判断是否到达尾节点就可以了。

让我们来组装一下代码吧:

Node* ReverseList(Node *head) {
        Node *prev = null;
        Node *worker = null;
         
        if(head == null) {
            return null;
        }
 
        if(head.next == null) {
            return head;
        }
 
        prev = head.next;
        head.next = null;
        while(prev != null) {
            worker = head;
            head = prev;
            prev = head.next;
            head.next = worker;
        }
 
        return head;
         
 }

大功告成!

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值