图解ES6实现单向链表(添加)和反转功能

这几天在看算法基础,链表部分再练练手,单向链表的反转是一个比较考验思维缜密的技巧点。先在纸上画一下单向链表的结构,分析一下指向问题,基本得出解决思路(解决思路不复杂,但是要小心处理各个指针(引用)的指向关系):

1,基本得出解决思路

1,通过while循环遍历链表。

2,每次遍历都要分析出三层节点关系:父节点、子节点,孙节点。每次遍历都将子节点的next指针(引用)指向父节点。

3,遍历结束之后,获得当前链表的尾节点。

4,修正头节点head的next指针为null,变为尾节点用。

5,将头节点head指向尾节点。

注意:

特殊处理一下没有数据(head节点为空),和只有一个数据(head节点的next为空)

Talk is cheap, show me the code:

// 单向链表练习
class Node{
    constructor(data){
        this.data = data;
        this.next = null;
    }
}
class LinkTableSingle{
    constructor(){
        this.head = null;
    }
    add(data){
        const n = new Node(data);
        if(!this.head){
            this.head = n;
            return this;
        }
        let currentNode = this.head;
        while(currentNode.next !== null){
            currentNode = currentNode.next
        }
        currentNode.next = n;
        return this;        
    }

    // 挑战单向链表的反转,这里算三个指针(引用的移动问题吧)
    reverse(){
        let parentNode = this.head;
        // 没有节点或者只有一个节点,不需要反转
        if(parentNode ===null || parentNode.next ===null){
            return;
        }
        let childNode = parentNode.next;        
        while(childNode){
            let grandChildNode = childNode.next;
            childNode.next = parentNode;
            parentNode = childNode; 
            childNode = grandChildNode;
        }
        this.head.next = null;
        // 把head节点指向最后一个节点,如果sub节点已经为null了,那么此时的parent节点就是最后一个节点。
        this.head = parentNode;
    }
}

// 测试一下:
function test(){
    const lt = new LinkTableSingle();
    lt.add("a");
    lt.add("b");
    lt.add("c");
    lt.add("d");
    lt.add("e");
    lt.reverse();
    console.log(lt);
}

test()

2,图解反转过程:

高清图:https://www.processon.com/view/link/6120c902f346fb785d212b9e

先直观的看看添加完数据的链表和反转后的链表图

直观的看完单向链表存储的数据及反转后的效果后,咱们看看具体步骤:

步骤1:通过while循环找到第一个父节点、子节点、孙节点,技巧:定义一个变量,引用子节点的next,就是孙节点。

步骤2:反转子节点的next,将其指向改为父节点:

步骤3:将当前子节点作为下一次循环的父节点;当前孙节点作为下一次的子节点,继续下一次循环。

 

 

步骤4:循环遍历完整个链表,此时父节点指向了最后一个节点。

 

 步骤5:修正头节点和尾节点:

this.head.next = null;
this.head = parentNode;

 3,备注上画图地址:

https://www.processon.com/view/link/6120c902f346fb785d212b9e

画图不容易,写代码和调试花了半个多小时。画图花了两个多小时,也算值得。这次更清晰了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值