JS基于引用类型实现双向链表以及常用方法

function DoublyLinkArray() {
    // 定义实例属性
    this.length = 0; // 链表长度
    this.head = null; // 头节点
    this.tail = null; // 尾结点

    // 定义内部函数
    function Node(data) {
        this.data = data;
        this.prev = null;  // 指向前一个结点的指针   
        this.next = null;   // 指向后一个结点的指针
    }

    // 往后面添加一个元素
    DoublyLinkArray.prototype.append = function (data) {
        var newNode = new Node(data);

        if (this.head == null) {
            this.head = newNode;
            this.tail = newNode;
        }
        else {
            newNode.prev = this.tail;
            this.tail.next = newNode;
            this.tail = newNode;
        }

        this.length++;
    }

    // 打印元素
    DoublyLinkArray.prototype.toString = function () {
        return this.forwardString();
    }

    // 从前往后打印元素
    DoublyLinkArray.prototype.backwardString = function () {
        var string = "";
        var current = this.head;
        while (current) {
            string += current.data + " ";
            current = current.next;
        }
        return string;
    }

    // 从后往前打印元素
    DoublyLinkArray.prototype.forwardString = function () {
        var string = "";
        var current = this.tail;
        while (current) {
            string += current.data + " ";
            current = current.prev;          // 头结点的prev为空
        }
        return string;
    }

    // 插入元素
    DoublyLinkArray.prototype.insert = function (position, data) {

        // 创建元素
        var newNode = new Node(data);

        // 元素为空的情况
        if (this.head == null) {
            this.head = newNode;
            this.tail = newNode;
            this.length++;
            return true;
        }

        // 边界判断
        if (position < 0 || position >= this.length) return false;


        /* 插入分为三种情况*/
        // 头插入
        if (position == 0) {
            newNode.next = this.head;
            this.head.prev = newNode;
            this.head = newNode;
        }

        // 尾插入
        else if (position == this.length - 1) {
            newNode.prev = this.tail;
            this.tail.next = newNode;
            this.tail = newNode;
        }

        // 中间插入 找到要插入结点的前一个结点
        else {
            var currentFront = this.head;   // 当前结点的前一个结点
            var index = 0;
            while (index++ != position - 1) {
                currentFront = currentFront.next;
            }
            var currentNext = currentFront.next; // 当前结点的后一个结点
            currentFront.next = newNode;
            newNode.prev = currentFront;
            newNode.next = currentNext;
            currentNext.prev = newNode;
        }
        this.length++;
        return true;
    }

    // 根据下标获取数据
    DoublyLinkArray.prototype.get = function (position) {
        // 边界判断
        if (position < 0 || position >= this.length) return null;

        /* 利用双向链表的特性 判断是从前往后找 还是从后往前找*/
        var backward = this.length / 2 > position ? true : false;
        // 从前往后
        if (backward) {
            var index = 0;
            var current = this.head;
            while (index++ != position) {
                current = current.next;
            }
        }
        // 从后往前
        else {
            var index = this.length - 1;
            var current = this.tail;
            while (index-- != position) {
                current = current.prev;
            }
        }

        return current.data;
    }

    // 查找元素,返回下标。
    DoublyLinkArray.prototype.indexOf = function (data) {
        var current = this.head;
        var index = 0;
        while (current) {
            if (current.data == data) {
                return index;
            }
            current = current.next;
            index++;
        }

        if (current == null) {
            return -1;
        }
    }

    // 更新元素
    DoublyLinkArray.prototype.upDate = function (data, position) {
        // 边界判断
        if (position < 0 || position >= this.length) return false;

        /* 利用双向链表的特性 判断是从前往后找 还是从后往前找*/
        var backward = this.length / 2 > position ? true : false;

        // 从前往后
        if (backward) {
            var index = 0;
            var current = this.head;
            while (index++ != position) {
                current = current.next;
            }
        }
        // 从后往前
        else {
            var index = this.length - 1;
            var current = this.tail;
            while (index-- != position) {
                current = current.prev;
            }
        }

        current.data = data;

        return true;

    }

    // 根据下标,删除元素 返回元素值
    DoublyLinkArray.prototype.removeAt = function (position) {
        // 边界判断
        if (position < 0 || position >= this.length) return null;

        // 判断是否列表是否有值
        if (this.length == 0) {
            return null;
        }
        /*分三种情况删除*/
        // 头删除 
        if (position == 0) {
            var current = this.head;
            this.head = current.next;
            this.head.prev = null;
            this.length--;
            return current.data;
        }
        // 尾删除       
        else if (position == this.length - 1) {
            var current = this.tail;
            this.tail = current.prev;
            this.tail.next = null;
            this.length--;
            return current.data;
        }
        // 中间删除
        else {
            /* 利用双向链表的特性 判断是从前往后找 还是从后往前找*/
            var backward = this.length / 2 > position ? true : false;
            // 从前往后
            if (backward) {
                var index = 0;
                var current = this.head;
                while (index++ != position) {
                    current = current.next;
                }
            }
            // 从后往前
            else {
                var index = this.length - 1;
                var current = this.tail;
                while (index-- != position) {
                    current = current.prev;
                }
            }
            current.prev.next = current.next;
            current.next.prev = current.prev;
            this.length--;
            return current.data;
        }
    }

    // 根据值 删除元素
    DoublyLinkArray.prototype.remove = function(data) {
        var position = this.indexOf(data);
        return this.removeAt(position);
    }

    DoublyLinkArray.prototype.size = function() {
        return this.length;
    }

    DoublyLinkArray.prototype.isEmpty = function() {
        return this.length == 0 ? true:false;
    }
    // 获取尾元素的值
    DoublyLinkArray.prototype.getTail = function() {
        return this.tail.data;
    }

    // 获取头元素的值
    DoublyLinkArray.prototype.getHead = function() {
        return this.head.data;
    }


}

var link = new DoublyLinkArray();


link.insert(0, "好1")
link.insert(0, "好2")
link.insert(0, "好3")
link.insert(0, "好4")

console.log(link.backwardString())

link.remove("好444");

console.log(link.backwardString())

 

posted @ 2020-04-04 14:38  正义de键盘侠  阅读(129)  评论(0)    收藏  举报