JavaScipt实现循环链表

什么是循环链表

循环链表本质是一种特殊的单链表。循环链表和单链表之间唯一的区别在于,最后一个元素指向下一个元素的指针(tail.next)不是引用 undefined,而是指向第一个元素(head)

单链表是什么,如何封装 

详见:

https://blog.csdn.net/weixin_60629460/article/details/135864084

循环链表的封装

方法与单链表类似 

import Node from "./Node.mjs";
class CircularLinkedList {
    //记录链表的长度
    #length = 0
    //指向链表头的指针
    #head = null
    //链尾添加一个结点
    push(data) {
        //创建一个结点
        const node = new Node(data)
        if (this.#head === null/*链表为空时*/) {
            //把node作为链头
            this.#head = node
        } else/*链表不为空*/ {
            //先找到最后一个结点
            let last = this.getNodeAt(this.size() - 1)
            //插入node
            last.next = node
        }
        //node指会head形成环状
        node.next = this.#head
        //链表长度增加
        this.#length++
    }
    //找到指定位置的结点
    getNodeAt(index) {
        if (index >= 0 && index < this.#length) {
            let node = this.#head
            for (let i = 0; i < index; i++) {
                node = node.next
            }
            return node
        }
        return
    }
    size(){
        return this.#length
    }
    //在指定位置添加指定数据
    insert(data,index){
        //判断index是否存在
        if(index >= 0 && index <= this.#length){
            //创建新的node
            const node = new Node(data)
            let current = this.#head
            if(index === 0/*在链表头插入数据*/){
                if(this.#head === null/*链表为空时*/){
                    //node结点作为新的链表头
                    this.#head = node
                    //闭环
                    node.next = this.#head
                }else/*链表不为空时*/{
                    //用临时变量开辟一个空间用于插入node,暂时指向head
                    let temp = this.#head
                    //把node添加在head前
                    node.next = temp
                    //先找到最后一个结点
                    let last = this.getNodeAt(this.size() - 1)
                    //再node作为新的链表头
                    this.#head = node
                    //最后一个结点指向链头
                    last.next = this.#head
                }
            }else/*链表中插入*/{
                //先找到需要插入位置的上一结点
                const previous = this.getNodeAt(index - 1)
                //插入node(将node与插入位置后面的结点连接上)
                node.next = previous.next
                //将插入位置的前一个结点连接上node
                previous.next = node
            }
            this.#length++
            return true
        }
        return false
    }
    removeAt(index){
        //先判断index是否存在
        if(index >= 0 && index < this.#length){
            //用临时变量保护将被删除的结点(暂时指向head)
            let current = this.#head
            if(index === 0/*在链表头删除*/){
                if(this.#length === 1/*链表只有一个结点*/){
                    //head赋为null
                    this.#head = null
                }else/*链表有多个结点*/{
                    //找出最后一个结点
                    let last = this.getNodeAt(this.size() - 1)
                    //空出原来的头结点
                    this.#head = this.#head.next
                    //闭环
                    last.next = this.#head
                }
            }else/*链表中插入*/{
                //找到上一结点
                const previous = this.getNodeAt(index - 1)
                //保护要被删除的结点
                current = previous.next
                //将链表重新连接上
                previous.next = current.next
            }
            this.#length--
            return current.data
        }
        return
    }
    clear(){
        this.#head = null
        this.#length = 0
    }
    indexOf(data){
        let current = this.#head
        for(let i = 0; i < this.#length; i++){
            if(JSON.stringify(data) === JSON.stringify(current.data)){
                return i
            }
            current = current.next
        }
        return -1
    }
    remove(data){
        const index = this.indexOf(data)
        return this.removeAt(index)
    }
    getHead(){
        return this.#head
    }
    toString(){
        let string = ''
        let current = this.#head
        while(current){
            string += current.data + (current.data?',':'')
            current = current.next
        }
        return string
    }
    isEmpty(){
        return this.size() === 0
    }
}
export default CircularLinkedList

 

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

根号三;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值