js封装一个双链表

// 封装一个双向链表
function DoublyLinkedList() {
    // 内部属性
    this.head = null;
    this.tail = null;
    this.length = 0;
    // 内部类,存放节点的数据和指针
    function Node(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
    // append 向链表的最后添加节点
    DoublyLinkedList.prototype.append = function (data) {
        let newNode = new Node(data);
        if (!this.length) {
            this.head = newNode;
        } else {
            newNode.prev = this.tail;
            this.tail.next = newNode;
        }
        this.tail = newNode;
        this.length++;
        return this.length

    }
    // toString
    DoublyLinkedList.prototype.toString = function () {
        return this.backwardString()
    }
    // backwardString  往后遍历得到一个字符串
    DoublyLinkedList.prototype.backwardString = function () {
        let current = this.head;
        let str = '';
        while (current) {
            str += current.data + ' ';
            current = current.next;
        }
        return str
    }
    // forwardString  往前遍历得到一个字符串
    DoublyLinkedList.prototype.forwardString = function () {
        let previous = this.tail;
        let str = '';
        while (previous) {
            str += previous.data + ' ';
            previous = previous.prev;
        }
        return str
    }
    // insert   向链表中插入一个节点
    DoublyLinkedList.prototype.insert = function (position, data) {
        // 越界判断
        if (position < 0 || position > this.length) return false;
        // 创建一个节点
        let newNode = new Node(data);
        // 链表长度为0时
        if (this.length == 0) {
            this.head = newNode;
            this.tail = newNode;
            this.length++;
            return true
        }
        // 插入到头部
        if (position === 0) {
            newNode.next = this.head;
            this.head.prev = newNode;
            this.head = newNode;
        } else if (position === this.length) {
            // 插入到尾部
            newNode.prev = this.tail;
            this.tail.next = newNode;
            this.tail = newNode;
        } else {
            // 插入到其它位置
            let current = this.head;
            let index = 0;
            while (index++ < position) {
                current = current.next;
            }
            newNode.next = current;
            newNode.prev = current.prev;
            current.prev.next = newNode;
            current.prev = newNode;
        }
        this.length++;
        return true
    }
    // removeAt   通过索引删除相应的节点
    DoublyLinkedList.prototype.removeAt = function (position) {
        // 越界判断
        if (position < 0 || position >= this.length) return false;

        let current = this.head;
        // 如果只有一个节点时
        if (this.length === 1) {
            this.head = null;
            this.tail = null;
            this.length--;
            return current.data
        }

        // 删除头部节点
        if (position === 0) {
            this.head = this.head.next;
            this.head.prev = null;
        } else if (position === this.length - 1) {
            // 删除尾部节点
            current = this.tail;
            this.tail = this.tail.prev;
            this.tail.next = null;
            this.length--;
        } else {
            // 删除其它节点
            if (position < this.length / 2) {
                let index = 0;
                while (index++ < position) {
                    current = current.next
                }
            } else {
                let index = this.length - 1;
                while (index-- > position) {
                    current = current.prev
                }
            }
            current.prev.next = current.next;
            current.next.prev = current.prev;

        }
        this.length--;
        return current.data
    }
    // remove   通过信息删除相应的节点
    DoublyLinkedList.prototype.remove = function (data) {

        // 如果只有一个节点时
        if (this.length === 1) {
            this.head = null;
            this.tail = null;
            this.length--;
            return true
        }
        // 删除头部节点
        if (this.head.data === data) {
            this.head = this.head.next;
            this.head.prev = null;
            this.length--;
            return true
        } else if (this.tail.data === data) {
            // 删除尾部节点
            this.tail = this.tail.prev;
            this.tail.next = null;
            this.length--
            return true
        } else {
            // 删除其它节点
            let current = this.head;
            let previous = null;
            while (current) {
                previous = current;
                current = current.next;
                if (current && current.data === data) {
                    previous.next = current.next;
                    current.next.prev = previous;
                    this.length--;
                    return true
                }
            }
            return false
        }
    }
    // get  通过索引获取相应节点的信息
    DoublyLinkedList.prototype.get = function (position) {
        // 越界判断
        if (position < 0 || position >= this.length) return null;

        if (position < this.length / 2) {  // 从前往后遍历
            let current = this.head;
            let index = 0;
            while (index++ < position) {
                current = current.next;
            }
            return current.data
        } else {                // 从后往前遍历
            let current = this.tail;
            let index = this.length - 1;
            while (index-- > position) {
                current = current.prev;
            }
            return current.data
        }
    }
    // indexOf  通过节点的信息获取到相应的索引,没有的话返回-1
    DoublyLinkedList.prototype.indexOf = function (data) {
        if (this.tail.data === data) {
            return this.length - 1
        }
        let current = this.head;
        let index = 0;
        while (current) {
            if (current.data === data) {
                return index
            }
            current = current.next;
            index++;
        }
        return -1;
    }
    // update  修改节点的信息
    DoublyLinkedList.prototype.update = function (position, newData) {
        // 越界判断
        if (position < 0 || position >= this.length) return false;

        if (position < this.length / 2) {  // 从前往后遍历
            let current = this.head;
            let index = 0;
            while (index++ < position) {
                current = current.next
            }
            current.data = newData;
        } else {                // 从后往前遍历
            let current = this.tail;
            let index = this.length - 1;
            while (index-- > position) {
                current = current.prev;
            }
            current.data = newData;
        }
        return true;
    }
    // isEmpty  判断链表是否为空
    DoublyLinkedList.prototype.isEmpty = function () {
        return this.length == 0
    }
    // size     查看链表的长度
    DoublyLinkedList.prototype.size = function () {
        return this.length
    }
    // getHead  获取链表第一个节点
    DoublyLinkedList.prototype.getHead = function(){
        return this.head.data
    }
    // getTail  获取链表最后节点
    DoublyLinkedList.prototype.getTail = function(){
        return this.tail.data
    }

}
// ------ 测试--------
let d_list = new DoublyLinkedList();
d_list.append('帅的');
d_list.append('漂亮');
d_list.append('美德');
d_list.append('人才');
console.log(d_list);
console.log(d_list.backwardString());
console.log(d_list.forwardString());
console.log(d_list.insert(0, 'aa'));
console.log(d_list.insert(3, 'bb'));
console.log(d_list.insert(6, 'cc'));
console.log(d_list.toString());
// console.log(d_list.removeAt(6));
// console.log(d_list.get(0));
// console.log(d_list.indexOf('cc'));
// console.log(d_list.remove('aa'));
// console.log(d_list.remove('bb'));
// console.log(d_list.remove('cc'));
// console.log(d_list.remove('33'));
// console.log(d_list.toString());
// console.log(d_list.update(2, '33'));
// console.log(d_list.toString());
// console.log(d_list.isEmpty());
// console.log(d_list.size());
// console.log(d_list.getHead());
// console.log(d_list.getTail());

 

posted @ 2021-06-01 14:51  正经的流刺源  阅读(72)  评论(0编辑  收藏  举报