《JavaScript数据结构与算法》笔记——第5章 链表

  • 链表存储有序的元素集合,不一样于数组,链表中的元素在内存中并非连续放置,每一个元素有一个存取元素自己的节点和一个指向下一个元素的引用组成。

优势:添加或者移除元素的时候不须要移动其余元素。只须要找到加入的节点,断开并插入一个元素(修改引用)javascript

function LinkedList() {
    let Node = function (element) {// 辅助类,包含一个element属性即具体的值,以及一个next属性即指向下一个节点的引用
        this.element = element;
        this.next = null;
    };
    let length = 0;
    let head = null;
    /**
     * 向列表尾部添加一个新的项
     * @param element
     */
    this.append = function (element) {
        let node = new Node(element), current;
        if (head === null) {
            head = node;
        } else {
            current = head;
            // 循环列表找到最后一项
            while (current.next) {
                current = current.next
            }
            // 将最后一项的引用指向新元素(将最后一项的next指向node,创建新链接)
            current.next = node;
        }
        length++;// 更新列表的长度
    };
    /**
     * 向列表的特定位置插入一个新的项
     * @param position
     * @param element
     */
    this.insert = function (position, element) {
        if (position > -1 && position < length) {
            let node = new Node(element);
            let current = head, previous, index = 0;
            if (position === 0) {
                head = node;
                node.next = current
            } else {
                while (index++ < position) {
                    previous = current;
                    current = current.next
                }
                previous.next = node;
                node.next = current
            }
            length++;
            return true
        } else {
            return false
        }
    };
    /**
     * 从列表的特定位置移出一项
     * @param position
     */
    this.removeAt = function (position) {
        // 检查越界值
        if (position > -1 && position < length) {// 验证该位置是否有效
            // current是对要移出元素的引用
            // previous是对要移出的元素前一个元素的引用
            let current = head, index = 0, previous;
            // 移出第一项
            if (position === 0) {
                head = current.next;
            } else {
                while (index++ < position) {
                    previous = current;
                    current = current.next
                }
                // 将previous与current的下一项连接起来:这样跳过current,从而实现移出,垃圾收集
                previous.next = current.next
            }
            length--;
            return current.element
        } else {
            return null
        }
    };
    /**
     * 从列表移出一项
     * @param element
     */
    this.remove = function (element) {
        
    };
    /**
     * 返回元素在列表中的索引
     * @param element
     */
    this.indexOf = function (element) {
        let current = head, index = 0;
        while(current){
            if(element === current.element){// 断定条件须要优化,对于应用类型要断定值相等
                return index;
            }
            index++;
            current = current.next
        }
        return -1
    };
    this.isEmpty = function () {
    };
    this.size = function () {
    };
    this.getHead = function () {
    };
    /**
     * 因为使用Node辅助类,因此要重写继承自默认对象的toString方法
     */
    this.toString = function () {
        let current = head, string = '';
        while (current) {
            string += current.element + (current.next ? 'n' : '');
            current = current.next
        }
        return string
    };
    this.print = function () {
    }
}
  • 双向链表
  • 循环链表