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

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

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

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 () {
    }
}
  • 双向链表
  • 循环链表

相关推荐