图解JavaScript单向循环链表及其反转实现

上一篇讲解分析了一下单向链表的反转实现。再看一下单向循环链表的反转。

(高清图地址: https://www.processon.com/view/link/6121c41363768958e5302f6e )

1,直观的看一下区别:

先直观的看一下【单向链表】和【单向循环链表】的区别

 反转之后的指针(引用)指向:

2,实现策略:

2.1,从头节点开始遍历整个链表,直到找到尾节点

        循环尾节点的判断是【尾节点】等于【头节点】 ,之前单向非循环链表的尾节点判断是节点的next为null,注意区别。

2.2,每次遍历的时候,将相邻两个节点中,子节点的next指向前一个节点。

2.3,将当前头节点的next引用指针指向尾节点。

2.4,将头节点的指针(引用)this.head指向尾节点

2.5,注意:特殊处理一下链表数据为空(this.head === null )和只有一个节点(this.head.next === this.head)的情况,或者用this.length来判断。

上图:

 

3,上代码

// 单向链表练习
class Node{
    constructor(data){
        this.data = data;
        this.next = null;
    }
}
/**
 * 单向循环链表
 */
class CircularLinkTable{
    constructor(){
        this.head =null;
        this.length = 0;
    }
    /**
     * 往链表中添加数据
     * @param {*} data 
     * @returns 
     */
    add(data){
        const n = new Node(data);
        if(this.head === null) {
            this.head = n;
            n.next = this.head;    
            this.length++;        
            return true;
        }
        // 找到尾节点 
        let pre = this.head;       
        while(pre.next !== this.head){
            pre = pre.next;
        }
        if(pre.next === this.head){
            n.next = this.head;
            pre.next = n;
            this.length++;
            return true;        
        }else{
            console.error(`add error, did not find tail node!!!`)
            return false;
        }
    }

    /**
     * 反转链表
     * @returns 
     */
    reverse(){
        if(this.length<=1){
            return;
        }
        let pre = this.head;
        let current = pre.next;
        // while循环 遍历整个链表,反转next指向到父节点,并找到尾节点
        while(current.next !== this.head){  
            const next = current.next;     
            current.next = pre; // 反转next指向
            // 准备进入下一次搜索,搜索下一个节点
            pre = current;
            current = next;
        }
        // 此时的current就是尾节点
        current.next = pre;
        // 修正头节点的指向,修正头节点next的指向
        this.head.next = current;
        this.head = current;        
    }
}

// 测试
function test(){
    const lt = new CircularLinkTable();
    lt.add("a");
    lt.add("b");
    lt.add("c");
    lt.reverse();
    console.log(lt);
}
test();

备注:上一篇单向链表的反转:https://blog.csdn.net/yangxinxiang84/article/details/119842446

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值