简单手写栈、队列、链表实现

  1. //栈LIFO 先进后出
  2. // push 添加元素
  3. // pop 移除栈顶的元素
  4. // peek 获取栈顶的元素
  5. // isEmpty 是否为空
  6. // clean 清空栈
  7. // size 返回栈的长度
  8. let Stack = (function () {
  9. const _items = new WeakMap()
  10. return class Stack {
  11. constructor() {
  12. _items.set(this, [])
  13. }
  14. push(element) {
  15. _items.get(this).push(element)
  16. }
  17. pop() {
  18. return _items.get(this).pop()
  19. }
  20. peek() {
  21. return _items.get(this)[this.size() - 1]
  22. }
  23. isEmpty() {
  24. return _items.get(this).length === 0
  25. }
  26. clean() {
  27. _items.set(this, [])
  28. }
  29. size() {
  30. return _items.get(this).length
  31. }
  32. toString() {
  33. return _items.get(this).toString()
  34. }
  35. }
  36. })()
  37. var a = new Stack()
  38. a.push(1)
  39. a.push(2)
  40. a.push(3)
  41. a.push(4)
  42. a.pop()
  43. console.log(a.isEmpty())
  44. console.log(a.peek())
  45. console.log(a.size())
  46. console.log(a.toString())
  47. /** 进制转换就可以用到栈
  48. * 比如转二进制,以10为例,转成二进制就是1010
  49. * 转换过程:rem为余数
  50. * 10/2 = 5 , rem = 0
  51. * 5/2 = 2, rem = 1
  52. * 2/2 = 1, rem = 0
  53. * 1/2 = 0, rem = 1
  54. * 从上到下,就是 1010,就是10转二进制的结果
  55. * 由此可见,符合栈的先进后出
  56. */
  57. function divide(num, base = 2) {
  58. var remStack = new Stack();
  59. var rem,
  60. res = "",
  61. digits = "0123456789abcdef"; // 16进制大于9的时候转化成字母
  62. while (num > 0) {
  63. rem = num % base;
  64. remStack.push(rem);
  65. num = parseInt(num / base);
  66. }
  67. while (!remStack.isEmpty()) {
  68. res += digits[remStack.pop()]
  69. }
  70. return res
  71. }
  72. console.log(divide(1000, 16));

队列

  1. // 队列Queue FIFO 先进先出
  2. // enqueue 进入队列
  3. // dequeue 退出队列
  4. // front 队列第一位
  5. // isEmpty 是否为空
  6. // size 队列长度
  7. // toString 输出队列
  8. let Queue = (function () {
  9. const _items = new WeakMap()
  10. return class Queue {
  11. constructor() {
  12. _items.set(this, [])
  13. }
  14. enqueue(element) {
  15. _items.get(this).push(element)
  16. }
  17. dequeue() {
  18. return _items.get(this).shift()
  19. }
  20. front() {
  21. return _items.get(this)[0]
  22. }
  23. isEmpty() {
  24. return this.size === 0
  25. }
  26. size() {
  27. return _items.get(this).length
  28. }
  29. toString() {
  30. return _items.get(this).toString()
  31. }
  32. }
  33. })()
  34. var a = new Queue()
  35. a.enqueue(1)
  36. a.enqueue(2)
  37. a.enqueue(3)
  38. a.enqueue(4)
  39. a.enqueue(5)
  40. a.dequeue()
  41. console.log(a.front())
  42. console.log(a.isEmpty())
  43. console.log(a.size())
  44. console.log(a.toString())
  45. // 优先队列
  46. let Queue = (function () {
  47. const _items = new WeakMap()
  48. // 优先队列元素
  49. class QueueElement {
  50. constructor(element, priority) {
  51. this.element = element;
  52. this.priority = priority;
  53. }
  54. }
  55. return class Queue {
  56. constructor() {
  57. _items.set(this, [])
  58. }
  59. enqueue(element, priority) {
  60. let queueElement = new QueueElement(element, priority)
  61. let added = false
  62. for (var i = 0; i < this.size(); i++) {
  63. if (queueElement.priority < _items.get(this)[i].priority) {
  64. _items.get(this).splice(i, 0, queueElement);
  65. added = true
  66. break
  67. }
  68. }
  69. if (!added) {
  70. _items.get(this).push(queueElement)
  71. }
  72. }
  73. dequeue() {
  74. return _items.get(this).shift()
  75. }
  76. front() {
  77. return _items.get(this)[0]
  78. }
  79. isEmpty() {
  80. return this.size === 0
  81. }
  82. size() {
  83. return _items.get(this).length
  84. }
  85. toString() {
  86. return _items.get(this)
  87. }
  88. }
  89. })()
  90. var a = new Queue()
  91. a.enqueue("张三", 1)
  92. a.enqueue("李四", 2)
  93. a.enqueue("赵六", 3)
  94. a.enqueue("熊七", 4)
  95. a.enqueue("赵八", 2)
  96. // a.dequeue()
  97. console.log(a.front())
  98. console.log(a.isEmpty())
  99. console.log(a.size())
  100. console.dir(a.toString())

链表

单向链表

  1. // 链表
  2. class Node {
  3. constructor(element) {
  4. this.element = element
  5. this.next = null
  6. }
  7. }
  8. class LinkedList {
  9. constructor() {
  10. this.head = null;
  11. this.size = 0;
  12. }
  13. getNode(index) {
  14. if (index < 0 || index >= this.size) {
  15. throw new Error("out of range")
  16. }
  17. let current = this.head
  18. for (var i = 0; i < index; i++) {
  19. current = current.next
  20. }
  21. return current
  22. }
  23. append(element) {
  24. let node = new Node(element)
  25. if (this.head === null) {
  26. this.head = node
  27. } else {
  28. let current = this.getNode(this.size - 1)
  29. current.next = node;
  30. }
  31. this.size++
  32. }
  33. appendAt(element, position) {
  34. let node = new Node(element)
  35. if (position === 0) {
  36. node.next = this.head
  37. this.head = node
  38. } else {
  39. let pre = this.getNode(position - 1);
  40. node.next = pre.next
  41. pre.next = node;
  42. }
  43. this.size++
  44. }
  45. indexOf(element) {
  46. let current = this.head
  47. for (var i = 0; i < index; i++) {
  48. if (current.element === element) {
  49. return i
  50. }
  51. current = current.next
  52. }
  53. return -1
  54. }
  55. removeAt(position) {
  56. let current = this.head
  57. if (position === 0) {
  58. this.head = current.head
  59. } else {
  60. let pre = this.getNode(position - 1)
  61. current = pre.next
  62. pre.next = current.next
  63. }
  64. this.size--
  65. }
  66. }
  67. let ll = new LinkedList()
  68. ll.append(1)
  69. ll.append(2)
  70. ll.append(3)
  71. ll.appendAt(4, 1)
  72. ll.removeAt(2)
  73. console.dir(ll, {
  74. depth: 1000
  75. })