五、双向链表

一、什么是双向链表?

其实上一节我们说的链表是单向链表.而双向链表的区别在于:

  • 既可以从头遍历到尾,也可以从尾遍历到头
  • 一个节点既有指向前一个元素的引用,也有一个指向后一个元素的引用

当然他也有一些缺点:

  • 每次在插入或删除某个节点时,需要处理四个引用,而不是两个
  • 相对于单向链表,必然占用的空间内存更大一些

但这些缺点和我们使用起来的方便程度相比,是微不足道的

class DoubleNode {
    constructor(data){
        this.data = data
        this.prev = null
        this.next = null
    }
}

class DoubleLinkedList{
    constructor() {
        this.head = null
        this.tail = null
        this.length = 0
    }

    // 操作方法
    // 添加一个新的项
    append(data) {
        let newNode = new DoubleNode(data)
        if(!this.head){
            this.head = newNode
            this.tail = newNode
        }else{
            newNode.prev = this.tail
            this.tail.next = newNode
            this.tail = newNode

        }
        this.length +=1
    }

    // 特定位置插入一个元素
    insert(data, position){
        if(position < 0 || position > this.length) return false
        let newNode = new DoubleNode(data)
        if(this.length === 0){
            this.head = newNode
            this.tail = newNode
        }else{
            if(position === 0){
                this.head.prev = newNode
                newNode.next = this.head
                this.head = newNode
            }else if(position === this.length){
                this.tail.next = newNode
                newNode.prev = this.tail
                this.tail = newNode
            }else{
                let index = 0
                let curNode = this.head
                while(index++ < position){
                    curNode = curNode.next
                }
                newNode.prev = curNode.prev
                newNode.next = curNode
                curNode.prev.next = newNode
                curNode.prev = newNode
            }
        }
        this.length += 1
        return true
    }

    // 获取对应位置元素
    get(position){
        if(position < 0 || position >= this.length) return null
        let index = 0
        let curNode = this.head
        while(index++ < position){
            curNode = curNode.next
        }
        return curNode.data
    }

    // 返回元素在链表中的位置,没有的话返回 -1
    indexOf(data){
        if(this.length === 0) return -1
        let curNode = this.head
        let index = 0
        while(curNode.next){
            if(curNode.data === data){
                return index
            }
            index += 1
            curNode = curNode.next
        }
        return -1
    }

    // 修改某个位置元素
    update(position, data){
        if(position < 0 || position >= this.length) return false
        let curNode = this.head
        let index = 0
        while(index++ < position){
            curNode = curNode.next
        }
        curNode.data = data
        return true
    }

    // 删除某个位置的项
    removeAt(position){
        if(position < 0 || position >= this.length) return false
        let curNode = this.head
        if(this.length === 1){
            this.head = null
            this.tail = null
        }else{
            if(position === 0){
                this.head.next.prev = null
                this.head = this.head.next
            }else if(position === this.length-1){
                curNode = this.tail
                this.tail.prev.next = null
                this.tail = this.tail.prev
            }else{
                let index = 0
                while(index++ < position){
                    curNode = curNode.next
                }
                curNode.prev.next = curNode.next
                curNode.next.prev = curNode.prev
            }
        }
        this.length -= 1
        return curNode.data
    }
    // 删除某个项
    remove(data){
        let position = this.indexOf(data)
        if(position === -1) return false
        return this.removeAt(position)
    }


    isEmpty(){
        return this.length === 0
    }

    size(){
        return this.length
    }

    // toString
    toString(){
        let curNode = this.head
        let str = ''
        while(curNode){
            str += curNode.data + ' '
            curNode = curNode.next
        }
        return str
    }
    // forwardString
    forwardString(){
        let curNode = this.tail
        let str = ''
        while(curNode){
            str += curNode.data + ' '
            curNode = curNode.prev
        }
        return str
    }
    // backwardString
    backwardString(){
        let curNode = this.head
        let str = ''
        while(curNode){
            str += curNode.data + ' '
            curNode = curNode.next
        }
        return str
    }
}

let h = new DoubleLinkedList()
h.append('df')
h.append('2')
// h.append('3')
h.insert('dfd',2)
h.append('dfd',3)
h.update(10, 11)
// h.append('4')
console.log(h.remove('2'))
// console.log(h.get(1))
console.log(h.toString())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值