zoukankan      html  css  js  c++  java
  • JavaScript数据结构——链表

    链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
    好处:可以添加或移除任意项,它会按需扩容,且不需要移动其他元素。
     
    与数组的区别
        数组:可以直接访问任何位置的任何元素;
        链表:想要访问链表中的一个元素,需要从起点(表头)开始迭代列表直到找到所需的元素。
     
    现实案例:康佳舞队、寻宝游戏
     
    单向链表:一个节点只有链向下一个节点的链接;
    双向链表:链接是双向的,一个链向下一个元素,另一个链向前一个元素
    优点:双向链表提供了两种迭代列表的方法:从头到尾,或者反过来。我们也可以访问一个特定节点的下一个或前一个元素。在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表起点,重新开始迭代。
    -------------------------------------------------------------------------------------------------------------
    链表方法声明:
    1. 定义Node辅助类;
    2. 内部属性 length;
    2. 存储第一个节点(head)的引用
    序号
    方法
    说明
    1
    append(element) 向列表尾部添加一个新的项
    2
    insert(position, element) 向列表的特定位置插入一个新的项
    3
    remove(element)
    从列表中移除一项
    4
    indexOf (element )
    返回元素在列表中的索引。如果列表中没有该元素则返回-1
    5
    removeAt(position)
    从列表的特定位置移除一项
    6
    isEmpty()
    如果链表中不包含任何元素,返回 true,如果链表长度大于 0 则返回 false
    7
    size ( )
    返回链表包含元素个数。与数组的 length 属性类似
    8
    toString ( )
    由于列表项使用了 Node 类,就需要重写继承自 JavaScript 对象默认的 toString 方法,让其只输出元素的值

    链表实现:

      1 function LinkedList() {
      2     // 定义辅助类Node
      3     var Node = function(element) {
      4         this.element = element;    // element属性,即要添加到列表的元素
      5         this.next = null;    // next属性,即指向列表中下一个节点项的指针
      6     }
      7 
      8     var length = 0;    // 内部属性/私有变量
      9     var head = null;    // 第一个节点的引用
     10 
     11     // 向列表的尾部添加一个新的项
     12     this.append = function(element) {
     13         var node = new Node(element),    // 把element作为值传入,创建Node项
     14             current;
     15 
     16         if (head === null) {    // 列表中第一个节点,如果head元素为null,则意味着向列表添加第一个元素
     17             head = node;    // head指向node元素,下一个node将会自动生成null
     18         } else {
     19             current = head;
     20 
     21             // 循环列表,直到找到最后一项
     22             while(current.next) {
     23                 current = current.next;
     24             }
     25 
     26             // 找到最后一项,将其next赋为node,建立连接
     27             current.next = node;    // 列表中最后一个节点的下一个元素始终是null
     28         }
     29 
     30         length++;    // 更新链表长度,这样就能控制它,轻松地得到列表的长度
     31     };
     32 
     33     // 向列表的特定位置插入一个新的项
     34     this.insert = function(position, element) {
     35         // 检查越界值
     36         if (position >= 0 && position <= length) {
     37             var node = new Node(element),
     38                 current = head,
     39                 previous,
     40                 index = 0;
     41 
     42             if (position === 0) {    // 在第一个位置添加
     43                 node.next = current;
     44                 head = node;
     45             } else {
     46                 while (index++ < position) {
     47                     previous = current;
     48                     current = current.next;
     49                 }
     50                 node.next = current;
     51                 previous.next = node;
     52             }
     53 
     54             length++;
     55 
     56             return true;
     57 
     58         } else {
     59             return false;
     60         }
     61     };
     62 
     63     // 从列表的特定位置移除一项
     64     this.removeAt = function(position) {
     65         // 检查越界值
     66         if (position > -1 && position < length) {
     67             var current = head,    // current变量总是为对所循环列表的当前元素的引用
     68                 previous,    // previous变量为对当前元素的前一个元素的引用
     69                 index = 0;
     70 
     71             // 移除第一项
     72             if (position === 0) {
     73                 head = current.next;
     74             } else {
     75                 while (index++ < position) {    // 使用用于内部控制和递增的index变量来迭代列表
     76                     previous = current;    
     77                     current = current.next;
     78                 }
     79 
     80                 // 将previous与current的下一项链接起来:跳过current,从而移除它
     81                 previous.next = current.next;
     82             }
     83 
     84             length--;
     85 
     86             return current.element;
     87         } else {
     88             return null;
     89         }
     90     };
     91 
     92     // 从列表中移除一项
     93     this.remove = function(element) {
     94         var index = this.indexOf(element);
     95         return this.removeAt(index);
     96     };
     97 
     98     // 返回元素在列表中的索引。如果列表中没有该元素则返回-1
     99     this.indexOf = function(element) {
    100         var current = head,
    101             index = -1;
    102 
    103         while (current) {
    104             if (element === current.element) {
    105                 return index;
    106             }
    107             index++;
    108             current = current.next;
    109         }
    110 
    111         return -1;
    112     };
    113 
    114     // 如果链表中不包含任何元素,返回 true,如果链表长度大于 0 则返回 false
    115     this.isEmpty = function() {
    116         return length === 0;
    117     };
    118 
    119     // 返回链表包含元素个数。与数组的 length 属性类似
    120     this.size = function() {
    121         return length;
    122     };
    123 
    124     // 由于列表项使用了 Node 类,就需要重写继承自 JavaScript 对象默认的 toString 方法,让其只输出元素的值
    125     this.toString = function() {
    126         var current = head,
    127             string = '';
    128 
    129         while (current) {
    130             string += current.element;
    131             current = current.next;
    132         }
    133 
    134         return string;
    135     };
    136 
    137     this.getHead = function () {
    138         return head;
    139     };
    140 }
    LinkedList.js
     
    双向链表实现:
     1 function DoublyLinkedList() {
     2     var Node = function(element) {
     3         this.element = element;
     4         this.next = null;
     5         this.prev = null;
     6     };
     7 
     8     var length = 0;
     9     var head = null;
    10     var tail = null;    // 新增的
    11 
    12     // 特定位置插入元素
    13     this.insert = function(position, element) {
    14         // 检查越界值
    15         if (position >= 0 && position <= length) {
    16             var node = new Node(element),
    17                 current = head,
    18                 previous,
    19                 index = 0;
    20 
    21             if (position === 0) {    // 在第一个位置添加
    22                 if (!head) {    // 新增的
    23                     head = node;
    24                     tail = node;
    25                 } else {
    26                     node.next = current;
    27                     current.prev = node;
    28                     head = node;
    29                 }
    30             } else if (position === length-1) {    // 最后一项 //新增的
    31                 current = tail;
    32                 current.next = node;
    33                 node.prev = current;
    34                 tail = node;
    35             } else {
    36                 while (index++ < position) {
    37                     previous = current;
    38                     previous.next = node;
    39                 }
    40 
    41                 node.next = current;
    42                 previous.next = node;
    43 
    44                 current.prev = node;    //新增的
    45                 node.prev = previous;    //新增的
    46             }
    47 
    48             length++;
    49             return true;
    50 
    51         } else {
    52             return false;
    53         }
    54     };
    55 
    56     // 特定位置删除元素
    57     this.removeAt = function(position) {
    58         // 检查越界值
    59         if (position > -1 && position < length) {
    60             var current = head,
    61                 previous,
    62                 index = 0;
    63 
    64             // 移除第一项
    65             if (position === 0) {
    66                 head = current.next;
    67 
    68                 // 如果只有一项,更新tail //新增的
    69                 if (length === 1) {
    70                     tail = null;
    71                 } else {
    72                     head.prev = null;
    73                 }
    74             } else if (position === length-1) {
    75                 current = tail;
    76                 tail = current.prev;
    77                 tail.next = null;
    78             } else {
    79                 while (index++ < position) {
    80                     previous = current;
    81                     current = current.next;
    82                 }
    83                 // 将prvious与current的下一项链接起来——跳过current
    84                 previous.next = current.next;
    85                 current.next.prev = previous;    // 新增的
    86             }
    87 
    88             length--;
    89 
    90             return current.element;
    91         } else {
    92             return null;
    93         }
    94     };
    95 }
    DoublyLinkedList.js

    参考书籍:《学习JavaScript数据结构与算法》

    Scoop It and Enjoy the Ride!
  • 相关阅读:
    DRF 配置
    RESTful 设计方法(学习总结用)
    Chrome 开发者工具
    html中注释的php代码被解析
    正则
    局域网域名访问php项目
    jQuery 操作from表单数据序列化
    jQuery操作Table tr td方法
    鼠标焦点在input的某个位置上,点击一个button 在input光标处的增加文字
    858. Mirror Reflection
  • 原文地址:https://www.cnblogs.com/Ruth92/p/5322050.html
Copyright © 2011-2022 走看看