LinkedList.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. var Class = require('./Class');
  2. exports = Class({
  3. initialize: function LinkedList() {
  4. this.tail = null;
  5. this.head = null;
  6. this.size = 0;
  7. },
  8. push: function(val) {
  9. var node = new Node(val, this.tail, null, this);
  10. this.tail = node;
  11. this.head = this.head || node;
  12. this.size++;
  13. return this.size;
  14. },
  15. pop: function() {
  16. if (!this.tail) return;
  17. var node = this.tail;
  18. this.tail = node.prev;
  19. if (this.tail) {
  20. this.tail.next = null;
  21. } else {
  22. this.head = null;
  23. }
  24. this.size--;
  25. return node.value;
  26. },
  27. unshift: function(val) {
  28. var node = new Node(val, null, this.head, this);
  29. this.head = node;
  30. this.tail = this.tail || node;
  31. this.size++;
  32. return this.size;
  33. },
  34. shift: function() {
  35. if (!this.head) return;
  36. var node = this.head;
  37. this.head = node.next;
  38. if (this.head) {
  39. this.head.prev = null;
  40. } else {
  41. this.tail = null;
  42. }
  43. this.size--;
  44. return node.value;
  45. },
  46. rmNode: function(node) {
  47. if (node.list !== this) {
  48. throw Error('Node does not belong to this list');
  49. }
  50. var next = node.next,
  51. prev = node.prev;
  52. if (next) {
  53. next.prev = prev;
  54. }
  55. if (prev) {
  56. prev.next = next;
  57. }
  58. if (node === this.head) {
  59. this.head = next;
  60. }
  61. if (node === this.tail) {
  62. this.tail = prev;
  63. }
  64. node.list = null;
  65. node.prev = null;
  66. node.next = null;
  67. this.size--;
  68. },
  69. find: function(fn) {
  70. for (var i = 0, current = this.head; current !== null; i++) {
  71. if (fn(current.value)) {
  72. return current;
  73. }
  74. current = current.next;
  75. }
  76. },
  77. forEach: function(iterator, ctx) {
  78. ctx = arguments.length > 1 ? ctx : this;
  79. for (var i = 0, current = this.head; current !== null; i++) {
  80. iterator.call(ctx, current.value, i, this);
  81. current = current.next;
  82. }
  83. },
  84. toArr: function() {
  85. var arr = new Array(this.size);
  86. for (var i = 0, current = this.head; current !== null; i++) {
  87. arr[i] = current.value;
  88. current = current.next;
  89. }
  90. return arr;
  91. }
  92. });
  93. var Node = (exports.Node = Class({
  94. initialize: function Node(val, prev, next, list) {
  95. this.value = val;
  96. this.list = list;
  97. if (prev) {
  98. prev.next = this;
  99. this.prev = prev;
  100. } else {
  101. this.prev = null;
  102. }
  103. if (next) {
  104. next.prev = this;
  105. this.next = next;
  106. } else {
  107. this.next = null;
  108. }
  109. }
  110. }));
  111. module.exports = exports;