【数据结构】链表--双向链表

双向链表: 

class DoubleNode {
    constructor(element) {
        this.data = element;
        this.previous = null;
        this.next = null;
    }
}
class DoubleList {
    constructor() {
        this.head = null;
        this.tail = null;
        this.length = 0;
    }
    append(element) {
        let newNode = new DoubleNode(element)
        if (this.head == null) {
            this.head = newNode;
            this.tail = newNode;
        } else {
            // 新节点p 指向尾部节点
            newNode.previous = this.tail
            // 尾部next指向新节点
            this.tail.next = newNode;
            // this.tail指向新节点
            this.tail = newNode
        }
        this.length++
    }
    insert(position, element) {
        // 越界判断
        if (position < 0 || position > this.length) {
            return false;
        }
        let newNode = new DoubleNode(element)
        if (position == 0) {
            // ** 19/10/16 改bug: 原代码未考虑空链表插入情况 **
            if (this.head != null) {
                // 将新节点的next指向头部节点
                newNode.next = this.head;
                // 头部节点的p指向新节点
                this.head.previous = newNode;
                // this.head指向新节点
                this.head = newNode;
            } else {
                this.head = newNode;
                this.tail = newNode;
            }
        } else if (position == this.length) {
            // 新节点p 指向尾部节点
            newNode.previous = this.tail
            // 尾部next指向新节点
            this.tail.next = newNode;
            // this.tail指向新节点
            this.tail = newNode
        } else {
            // 改为 position<length/2  从头开始
            // position>=length/2  从尾开始
            let current = this.head;
            let index = 0
            while (index++ != position) {
                current = current.next
            }
            // 新节点next指向当前节点
            newNode.next = current;
            // 新节点p指向当前节点的p
            newNode.previous = current.previous;
            // 当前节点的p的next指向新节点
            current.previous.next = newNode;
            // 当前节点的p指向新节点
            current.previous = newNode;
        }
        this.length++
        return true;
    }
    indexOf(element) {
        // 遍历链表
        let current = this.head;
        let index = 0
        while (current) {
            // 将链表中的值取出与element比较
            if (current.data === element) {
                // 相等 返回下标
                return index;
            }
            // 不相等 继续遍历
            current = current.next;
            index++;
        }

        // 遍历结束后仍未找到
        // 返回-1
        return -1;
    }
    //  返回最后一个相匹配的元素节点的下标
    lastIndexOf(element) {
        let current = this.tail;
        let index = this.length - 1;
        while (current) {
            if (current.data == element) {
                return index
            }
            current = current.previous;
            index--
        }
        return -1
    }
    removeAt(position) {
        if (position < 0 || position >= this.length) return false;
        if (position == 0) {
            // 将this.head的next的p指向null
            this.head.next.previous = null
            // 将this.head指向this.head 的next
            this.head = this.head.next
        } else if (position == this.length - 1) {
            this.tail = this.tail.previous
            this.tail.next = null
        } else {
            let current = this.head
            let index = 0
            while (index++ != position) {
                current = current.next;
            }
            current.previous.next = current.next
            current.next.previous = current.previous
        }

        this.length--;
        return true
    }
    remove(element) {
        return this.removeAt(this.indexOf(element))
    }
}

 

posted @ 2019-11-04 16:23  追僧逐月  阅读(115)  评论(0编辑  收藏  举报