JavaScript数据结构之-链表

链表数据结构

  • 要存储多个元素,可能经常使用的是数组。可是数组有一个缺点:在数组的起点和中间位置插入或移除项的成本很高,由于须要移动其它元素。链表相对于数组的好处就是添加或者删除元素不须要移动其余元素,可是要想访问链表中的元素,须要从链表的表头开始迭代列表直到找到所需元素。
  • 链表存储有序集合的元素,但不一样与数组,链表中的元素在内存中并非连续放置的。每一个元素由一个存储元素自己的节点和连接下一个元素的指针组成。

链式结构 node

建立链表

建立LinkedList,而且链表包含如下方法。数组

  • append(element):向链表尾部添加元素
  • insert(position, element):向链表指定位置添加元素
  • remove(element):删除指定元素
  • removeAt(position):删除指定位置的元素
  • indexOf(element):返回元素在链表的引索
  • isEmpty():链表是否为空
  • size():链表包含的元素个数
  • toString():输出元素的值
function LinkedList() {
    let length = 0, // 链表的长度
        head = null; // 链表的头指针
    // 辅助类
    let Node = function(element) {
        this.element = element;
        this.next = null;
    }
    // 向链表尾部添加指定元素
    this.append = function(element) {
        let node = new Node(element),
            current = '';
        if (head === null) {
            // 链表为空
            head = node;
        } else {
            // 链表不为空,迭代到链表最后一项,最后一项的指针等于node
            current = head;
            while (current.next) {
                current = current.next;
            }
            current.next = node;
        }
        length++;
    };
    // 从链表移除指定位置的元素
    this.removeAt = function(position) {
        // 检查是否越界
        if (position > -1 && position < length) {
            let current = head,
                previous = '',
                index = 0;
            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;
        }
    };
    // 在任意位置插入元素
    this.insert = function(position, element) {
        // 检查是否越界
        if (position > -1 && position < length) {
            let node = new Node(element),
                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;
        }
    };
    // 返回指定项的索引
    this.indexOf = function(element) {
        let current = head,
            index = 0;
        while (current) {
            if (element === current.element) {
                return index;
            } else {
                index++;
                current = current.next;
            }
        }
    };
    // 删除指定元素
    this.remove = function(element) {
        let index = this.indexOf(element);
        return this.removeAt(index, element);
    };
    // 链表是否为空
    this.isEmpty = function() {
        return length === 0;
    };
    // 链表长度
    this.size = function() {
        return length;
    };
    // 把链表转换为一个字符串
    this.toString = function() {
        let current = head,
            string = '';
        while(current) {
            string += current.element + (current.next ? 'n' : '');
            current = current.next;
        }
        return string;
    };
}
复制代码

// 向链表添加一项bash

// 链表删除一项

链表相对传统数组优势是:添加删除元素不会移动其它元素。数据结构

链表相对传统数组缺点是:访问链表中间的元素,须要从头迭代,直到找到所需元素。app

下一篇文章:双向链表、循环链表ui