单向链表
- class Node {
-     constructor(element) {
-         this.element = element;
-         this.next = null;
-     }
- }
- class LinkedList {
-     constructor() {
-         this.size = 0;
-         this.head = null;
-     }
-     /**
-      * @method 尾部追加数据
-      * @param {any} element 追加数据
-      */
-     append(element) {
-         let node = new Node(element);
-         if (this.head === null) {
-             this.head = node;
-         } else {
-             let current = this.getNode(this.size - 1);
-             current.next = node;
-         }
-         this.size++;
-     }
-     /**
-      * @method 指定位置追加数据
-      * @param {Number} position 位置
-      * @param {any} element 追加数据
-      */
-     appendAt(position, element) {
-         if (position < 0 || position > this.size) {
-             throw new Error("position out range");
-         }
-         let node = new Node(element);
-         if (position === 0) {
-             node.next = this.head;
-             this.head = node;
-         } else {
-             let pre = this.getNode(position - 1);
-             node.next = pre.next;
-             pre.next = node;
-         }
-         this.size++;
-     }
-     /**
-      * @method 删除指定位置数据
-      * @param {Number} position 位置
-      */
-     removeAt(position) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let current = this.head;
-         if (position === 0) {
-             this.head = current.next;
-         } else {
-             let pre = this.getNode(position - 1);
-             current = pre.next;
-             pre.next = current.next;
-         }
-         this.size--;
-     }
-     /**
-      * @method 修改指定位置数据
-      * @param {Number} position 位置
-      * @param {any} element 追加数据
-      */
-     update(position, element) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let pre = this.getNode(position);
-         pre.element = element;
-     }
-     /**
-      * @method 查找指定位置数据
-      * @param {Number} position 位置
-      * @return {any} 返回数据
-      */
-     getData(position) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let pre = this.getNode(position);
-         return pre.element;
-     }
-     /**
-      * @method 查找指定数据索引
-      * @param {any} element
-      * @return {Number} 索引
-      */
-     indexOf(element) {
-         let current = this.head;
-         // let i = 0;
-         // while (current) {
-         //     if (current.element === element) return i;
-         //     current = current.next;
-         //     i++;
-         // }
-         for (let i = 0; i < this.size; i++) {
-             if (current.element === element) {
-                 return i;
-             }
-             current = current.next;
-         }
-         return -1;
-     }
-     /**
-      * @method 返回链表长度
-      * @return {Number} 链表长度
-      */
-     get length() {
-         return this.size;
-     }
-     getNode(index) {
-         if (index < 0 || index >= this.size) {
-             throw new Error("out range");
-         }
-         let current = this.head;
-         // let i = 0;
-         // while (i++ < index) {
-         //     current = current.next;
-         // }
-         for (let i = 0; i < index; i++) {
-             current = current.next;
-         }
-         return current;
-     }
- }
- let ll = new LinkedList();
- ll.append(1);
- ll.append(2);
- // ll.append(3);
- // ll.append(4);
- ll.appendAt(2, 3);
- ll.appendAt(3, 4);
- // ll.appendAt(3, 2);
- // ll.removeAt(0);
- // ll.removeAt(1);
- console.log(ll.getData(3));
- // console.log(ll.indexOf(1));
- // console.log(ll.indexOf(2));
- // console.log(ll.indexOf(3));
- // console.log(ll.indexOf(4));
- // console.log(ll.indexOf(5));
- console.dir(ll, {
-     depth: 100,
- });
- console.log(ll.length);
- // setTimeout(() => {
- //     ll.update(3, 9);
- //     console.dir(ll, {
- //         depth: 100,
- //     });
- // }, 1000);
双向链表
- class DoublyNode {
-     constructor(element) {
-         this.element = element;
-         this.prev = null;
-         this.next = null;
-     }
- }
- class DoublyLinkedList {
-     constructor() {
-         this.size = 0;
-         this.head = null;
-         this.tail = null;
-     }
-     /**
-      * @method 尾部追加数据
-      * @param {any} element 追加数据
-      */
-     append(element) {
-         let node = new DoublyNode(element);
-         if (this.head === null) {
-             this.head = node;
-             this.tail = node;
-         } else {
-             this.tail.next = node;
-             node.prev = this.tail;
-             this.tail = node;
-         }
-         this.size++;
-     }
-     /**
-      * @method 指定位置追加数据
-      * @param {*} position 位置
-      * @param {*} element 追加数据
-      */
-     appendAt(position, element) {
-         if (position < 0 || position > this.size) {
-             throw new Error("position out range");
-         }
-         let node = new DoublyNode(element);
-         if (position === 0) {
-             if (this.head === null) {
-                 this.head = node;
-                 this.tail = node;
-             } else {
-                 node.next = this.head;
-                 this.head.perv = node;
-                 this.head = node;
-             }
-         } else if (position === this.size) {
-             this.tail.next = node;
-             node.prev = this.tail;
-             this.tail = node;
-         } else {
-             let pre = this.getNode(position - 1);
-             pre.next = node;
-             node.prev = pre;
-             node.next = pre.next;
-             pre.prev = node;
-         }
-         this.size++;
-     }
-     /**
-      * @method 删除指定位置数据
-      * @param {*} position 位置
-      */
-     removeAt(position) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let current = this.head;
-         if (position === 0) {
-             if (this.size === 1) {
-                 this.head = null;
-                 this.tail = null;
-             } else {
-                 this.head = current.next;
-                 this.head.prev = null;
-             }
-         } else if (position === this.size - 1) {
-             this.tail.prev.next = null;
-             this.tail = this.tail.prev;
-         } else {
-             let pre = this.getNode(position - 1);
-             current = pre.next;
-             pre.next = current.next;
-         }
-         this.size--;
-     }
-     /**
-      * @method 修改指定位置数据
-      * @param {Number} position 位置
-      * @param {any} element 追加数据
-      * TODO: 性能优化点 this.size / 2 > position 从头向后遍历, 反之则反
-      */
-     update(position, element) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let pre = this.getNode(position);
-         pre.element = element;
-     }
-     /**
-      * @method 查找指定位置数据
-      * @param {Number} position 位置
-      * @return {any} 返回数据
-      * TODO: 性能优化点 this.size / 2 > position 从头向后遍历, 反之则反
-      */
-     getData(position) {
-         if (position < 0 || position >= this.size) {
-             throw new Error("position out range");
-         }
-         let pre = this.getNode(position);
-         return pre.element;
-     }
-     /**
-      * @method 查找指定数据索引
-      * @param {Number} element
-      * @return {Number} 索引
-      */
-     indexOf(element) {
-         let current = this.head;
-         for (let i = 0; i < this.size; i++) {
-             if (current.element === element) {
-                 return i;
-             }
-             current = current.next;
-         }
-         return -1;
-     }
-     /**
-      * @method 返回链表长度
-      * @return {Number} 链表长度
-      */
-     get length() {
-         return this.size;
-     }
-     getNode(index) {
-         if (index < 0 || index >= this.size) {
-             throw new Error("out range");
-         }
-         let current = this.head;
-         for (let i = 0; i < index; i++) {
-             current = current.next;
-         }
-         return current;
-     }
- }
- let ll = new DoublyLinkedList();
- ll.append(1);
- ll.append(2);
- ll.append(3);
- ll.append(4);
- // ll.appendAt(2, 3);
- // ll.appendAt(3, 4);
- // ll.appendAt(3, 2);
- // ll.removeAt(0);
- // ll.removeAt(1);
- // console.log(ll.getData(3));
- // console.log(ll.indexOf(1));
- // console.log(ll.indexOf(2));
- // console.log(ll.indexOf(3));
- // console.log(ll.indexOf(4));
- // console.log(ll.indexOf(5));
- console.dir(ll, {
-     depth: 100,
- });
- console.log(ll.length);
- setTimeout(() => {
-     ll.update(3, 9);
-     console.dir(ll, {
-         depth: 100,
-     });
- }, 1000);
单向循环链表
双向循环链表
环形链表