zoukankan      html  css  js  c++  java
  • ES6的JavaScript数据结构实现之链表

    目的:ES6标准下的JS数据结构的一些实现代码。(作为记录和启发)

    内容:链表和双向链表,循环链表,有序链表。(未完成,待继续)

    所有源码在我的Github上(如果觉得不错记得给星鼓励我哦):ES6的JavaScript数据结构实现之链表

    一、基础数据结构

    1、链表

      1 class Node {
      2 constructor(element, next) {
      3 this.element = element;
      4 this.next = next;
      5 }
      6 }
      7 
      8 function defaultEquals(a, b) {
      9 return a === b;
     10 }
     11 
     12 class LinkedList {
     13 constructor(equalsFn = defaultEquals) {
     14 this.equalsFn = equalsFn;
     15 this.count = 0;
     16 this.head = undefined;
     17 }
     18 
     19 push(element){
     20 const node = new Node(element);
     21 let current;
     22 if (this.head == null){
     23 this.head = node;
     24 } else {
     25 current = this.head;
     26 while (current.next != null) {
     27 current = current.next;
     28 }
     29 current.next = node;
     30 }
     31 this.count++;
     32 }
     33 
     34 getElementAt(index) {
     35 if (index >= 0 && index <= this.count) {
     36 let node = this.head;
     37 for (let i = 0; i < index && node != null; i++) {
     38 node = node.next;
     39 }
     40 return node;
     41 }
     42 return undefined;
     43 }
     44 
     45 insert(element, index) {
     46 if (index >= 0 && index <= this.count) {
     47 const node = new Node(element);
     48 if (index ==0 ) {
     49 const current = this.head;
     50 node.next = current;
     51 this.head = node;
     52 } else {
     53 const previous = this.getElementAt(index - 1);
     54 node.next = previous.next;
     55 previous.next = node;
     56 }
     57 this.count++;
     58 return true;
     59 }
     60 return false;
     61 }
     62 
     63 removeAt(index) {
     64 if (index >= 0 && index < this.count) {
     65 let current = this.head;
     66 if (index == 0) {
     67 this.head = current.next; 
     68 }else {
     69 const previous = this.getElementAt(index - 1);
     70 current = previous.next;
     71 previous.next = current;
     72 
     73 }
     74 this.count--;
     75 return current.element;
     76 }
     77 return undefined;
     78 }
     79 
     80 remove(element) {
     81 const index = this.indexOf(element);
     82 return this.removeAt(index);
     83 }
     84 
     85 indexOf(element) {
     86 let current = this.head;
     87 for (let i = 0; i < this.count && current != null; i++) {
     88 if (this.equalsFn(element, current.element)) {
     89 return i;
     90 }
     91 current = current.next;
     92 } 
     93 return -1;
     94 }
     95 
     96 isEmpty() {
     97 return this.size() === 0;
     98 }
     99 
    100 size() {
    101 return this.count;
    102 }
    103 
    104 getHead() {
    105 return this.head;
    106 }
    107 
    108 clear() {
    109 this.head = undefined;
    110 this.count = 0;
    111 }
    112 
    113 toString() {
    114 if (this.head == null) {
    115 return '';
    116 }
    117 let objString = `${this.head.element}`;
    118 let current = this.head.next;
    119 for (let i = 1; i < this.size() && current != null; i++) {
    120 objString = `${objString},${current.element}`;
    121 current = current.next;
    122 }
    123 return objString;
    124 }
    125 }
    126 
    127 
    128 const list = new LinkedList();
    129 
    130 console.log(list);
    131 list.push(15);
    132 console.log(list);
    133 list.push(10);
    134 list.push(5);
    135 console.log(list);
    136 list.removeAt(1);
    137 console.log(list);
    138 list.insert(4,1);
    139 console.log(list);
    140 console.log(list.indexOf(15));
    141 console.log(list.indexOf(1));
    142 list.remove(15);
    143 console.log(list);
    144 
    145 LinkedList
    LinkedList

      

    2、双向链表

      1 class DoublyNode extends Node {
      2 constructor(element, next, prev) {
      3 super(element, next);
      4 this.prev = prev
      5 }
      6 }
      7 
      8 class DoublyLinkedList extends LinkedList {
      9 constructor(equalsFn = defaultEquals) {
     10 super (equalsFn);
     11 this.tail = undefined; 
     12 }
     13 push(element) {
     14 const node = new DoublyNode(element);
     15 if (this.head == null) {
     16 this.head = node;
     17 this.tail = node; // NEW
     18 } else {
     19 // attach to the tail node // NEW
     20 this.tail.next = node;
     21 node.prev = this.tail;
     22 this.tail = node;
     23 }
     24 this.count++;
     25 }
     26 insert(element, index) {
     27 if (index >= 0 && index <= this.count) {
     28 const node = new DoublyNode(element);
     29 let current = this.head;
     30 if (index == 0 ) {
     31 if(this.head == null) {
     32 this.head = node;
     33 this.tail = node;
     34 } else {
     35 node.next = this.head;
     36 this.head.prev = node;
     37 this.head = node;
     38 }
     39 } else if (index === this.count) {
     40 current = this.tail;
     41 current.next = node;
     42 node.prev = current;
     43 this.tail = node;
     44 } else {
     45 const previous = this.getElementAt(index - 1);
     46 current = previous.next; 
     47 node.next = current;
     48 previous.next = node;
     49 current.prev = node; 
     50 node.prev = previous;
     51 }
     52 this.count++;
     53 return true;
     54 }
     55 return false;
     56 }
     57 removeAt(index) {
     58 if (index >= 0 && index < this.count) {
     59 let current = this.head;
     60 if (index === 0) {
     61 this.head = this.head.next;
     62 if (this.count === 1) {
     63 this.tail = undefined;
     64 } else {
     65 this.head.prev = undefined;
     66 }
     67 } else if (index === this.count - 1) {
     68 current = this.tail;
     69 this.tail = current.prev;
     70 this.tail.next = undefined;
     71 } else {
     72 current = this.getElementAt(index);
     73 const previous = current.prev;
     74 previous.next = current.next;
     75 current.next.prev = previous;
     76 }
     77 this.count--;
     78 return current.element; 
     79 }
     80 return undefined;
     81 }
     82 indexOf(element) {
     83 let current = this.head;
     84 let index = 0;
     85 while (current != null) {
     86 if (this.equalsFn(element, current.element)) {
     87 return index;
     88 }
     89 index++;
     90 current = current.next;
     91 }
     92 return -1;
     93 }
     94 getHead() {
     95 return this.head;
     96 }
     97 getTail() {
     98 return this.tail;
     99 }
    100 clear() {
    101 super.clear();
    102 this.tail = undefined;
    103 }
    104 toString() {
    105 if (this.head == null) {
    106 return '';
    107 }
    108 let objString = `${this.head.element}`;
    109 let current = this.head.next;
    110 while (current != null) {
    111 objString = `${objString},${current.element}`;
    112 current = current.next;
    113 }
    114 return objString;
    115 }
    116 inverseToString() {
    117 // if (this.tail == null) {
    118 // return '';
    119 // }
    120 let objString = `${this.tail.element}`;
    121 let previous = this.tail.prev;
    122 while (previous != null) {
    123 objString = `${objString},${previous.element}`;
    124 previous = previous.prev;
    125 }
    126 return objString;
    127 }
    128 }
    129 
    130 
    131 const list = new DoublyLinkedList();
    132 list.push(20);
    133 console.log(list);
    134 list.push(19);
    135 list.push(18);
    136 console.log(list);
    137 list.insert(15, 1);
    138 console.log(list);
    139 list.removeAt(1);
    140 console.log(list);
    141 console.log(list.toString());
    142 console.log(list.inverseToString());
    DoublyNode

    3、循环链表(以扩展上述普通链表Linkedlist为例)

     1 class CircularLinkedList extends LinkedList {
     2   constructor(equalsFn = defaultEquals) {
     3     super(equalsFn);
     4   }
     5   push(element) {
     6     const node = new Node(element);
     7     let current;
     8     if (this.head == null) {
     9       this.head = node;
    10     } else {
    11       current = this.getElementAt(this.size() - 1);
    12       current.next = node;
    13     }
    14     // set node.next to head - to have circular list
    15     node.next = this.head;
    16     this.count++;
    17   }
    18   insert(element, index) {
    19     if (index >= 0 && index <= this.count) {
    20       const node = new Node(element);
    21       let current = this.head;
    22       if (index === 0) {
    23         if (this.head == null) {
    24           // if no node  in list
    25           this.head = node;
    26           node.next = this.head;
    27         } else {
    28           node.next = this.head;
    29           current = this.getElementAt(this.size());
    30           // update last element
    31           this.head = node;
    32           current.next = this.head;
    33         }
    34       } else {
    35         const previous = this.getElementAt(index - 1);
    36         node.next = previous.next;
    37         previous.next = node;
    38       }
    39       this.count++;
    40       return true;
    41     }
    42     return false;
    43   }
    44   removeAt(index) {
    45     if (index >= 0 && index < this.count) {
    46       let current = this.head;
    47       if (index === 0) {
    48         if (this.size() === 1) {
    49           this.head = undefined;
    50         } else {
    51           const removed = this.head;
    52           current = this.getElementAt(this.size() - 1);
    53           this.head = this.head.next;
    54           current.next = this.head;
    55           current = removed;
    56         }
    57       } else {
    58         // no need to update last element for circular list
    59         const previous = this.getElementAt(index - 1);
    60         current = previous.next;
    61         previous.next = current.next;
    62       }
    63       this.count--;
    64       return current.element;
    65     }
    66     return undefined;
    67   }
    68 }
    69 
    70 
    71 const list = new CircularLinkedList();
    72 
    73 list.push(20);
    74 console.log(list);
    75 list.push(19);
    76 list.push(18);
    77 console.log(list);
    78 list.insert(15, 0);
    79 console.log(list);
    80 list.removeAt(0);
    81 console.log(list);
    CircularLinkedList

    4、有序链表

     1 class Node {
     2   constructor(element, next) {
     3     this.element = element;
     4     this.next = next;
     5   }
     6 }
     7 
     8 function defaultEquals(a, b) {
     9   return a === b;
    10 }
    11 
    12 const Compare = {
    13   LESS_THAN: -1,
    14   BIGGER_THAN: 1,
    15   EQUALS: 0
    16 };
    17 
    18 function defaultCompare(a, b) {
    19   if (a === b) {
    20     return Compare.EQUALS;
    21   }
    22   return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
    23 }
    24 class SortedLinkedList extends LinkedList {
    25   constructor(equalsFn = defaultEquals, compareFn = defaultCompare) {
    26     super(equalsFn);
    27     this.equalsFn = equalsFn;
    28     this.compareFn = compareFn;
    29   }
    30   push(element) {
    31     if (this.isEmpty()) {
    32       super.push(element);
    33     } else {
    34       const index = this.getIndexNextSortedElement(element);
    35       super.insert(element, index);
    36     }
    37   }
    38   insert(element, index = 0) {
    39     if (this.isEmpty()) {
    40       return super.insert(element, index === 0 ? index : 0);
    41     }
    42     const pos = this.getIndexNextSortedElement(element);
    43     return super.insert(element, pos);
    44   }
    45   getIndexNextSortedElement(element) {
    46     let current = this.head;
    47     let i = 0;
    48     for (; i < this.size() && current; i++) {
    49       const comp = this.compareFn(element, current.element);
    50       if (comp === Compare.LESS_THAN) {
    51         return i;
    52       }
    53       current = current.next;
    54     }
    55     return i;
    56   }
    57 }
    58 
    59 const list = new SortedLinkedList();
    60 for (let i = 5; i > 0; i--) {
    61   list.push(i);
    62 }
    63 console.log(list);
    64 list.insert(1);
    65 console.log(list);
    SortedLinkedList
  • 相关阅读:
    计算机网络知识总结-网络安全
    域名恶意指向的解决方法
    域名恶意解析的原因是什么
    域名被人恶意解析的解决方法
    防止域名被恶意解析
    公安部网防G01-网站安全卫士软件/linux防御
    详解web容器
    关于 服务器ip和域名进行一个绑定
    重新温习软件设计之路(2)
    重新温习软件设计之路(1)
  • 原文地址:https://www.cnblogs.com/xinkuiwu/p/11644087.html
Copyright © 2011-2022 走看看