简单手写栈、队列、链表实现
栈
//栈LIFO 先进后出// push 添加元素// pop 移除栈顶的元素// peek 获取栈顶的元素// isEmpty 是否为空// clean 清空栈// size 返回栈的长度let Stack = (function () {const _items = new WeakMap()return class Stack {constructor() {_items.set(this, [])}push(element) {_items.get(this).push(element)}pop() {return _items.get(this).pop()}peek() {return _items.get(this)[this.size() - 1]}isEmpty() {return _items.get(this).length === 0}clean() {_items.set(this, [])}size() {return _items.get(this).length}toString() {return _items.get(this).toString()}}})()var a = new Stack()a.push(1)a.push(2)a.push(3)a.push(4)a.pop()console.log(a.isEmpty())console.log(a.peek())console.log(a.size())console.log(a.toString())/** 进制转换就可以用到栈* 比如转二进制,以10为例,转成二进制就是1010* 转换过程:rem为余数* 10/2 = 5 , rem = 0* 5/2 = 2, rem = 1* 2/2 = 1, rem = 0* 1/2 = 0, rem = 1* 从上到下,就是 1010,就是10转二进制的结果* 由此可见,符合栈的先进后出*/function divide(num, base = 2) {var remStack = new Stack();var rem,res = "",digits = "0123456789abcdef"; // 16进制大于9的时候转化成字母while (num > 0) {rem = num % base;remStack.push(rem);num = parseInt(num / base);}while (!remStack.isEmpty()) {res += digits[remStack.pop()]}return res}console.log(divide(1000, 16));
队列
// 队列Queue FIFO 先进先出// enqueue 进入队列// dequeue 退出队列// front 队列第一位// isEmpty 是否为空// size 队列长度// toString 输出队列let Queue = (function () {const _items = new WeakMap()return class Queue {constructor() {_items.set(this, [])}enqueue(element) {_items.get(this).push(element)}dequeue() {return _items.get(this).shift()}front() {return _items.get(this)[0]}isEmpty() {return this.size === 0}size() {return _items.get(this).length}toString() {return _items.get(this).toString()}}})()var a = new Queue()a.enqueue(1)a.enqueue(2)a.enqueue(3)a.enqueue(4)a.enqueue(5)a.dequeue()console.log(a.front())console.log(a.isEmpty())console.log(a.size())console.log(a.toString())// 优先队列let Queue = (function () {const _items = new WeakMap()// 优先队列元素class QueueElement {constructor(element, priority) {this.element = element;this.priority = priority;}}return class Queue {constructor() {_items.set(this, [])}enqueue(element, priority) {let queueElement = new QueueElement(element, priority)let added = falsefor (var i = 0; i < this.size(); i++) {if (queueElement.priority < _items.get(this)[i].priority) {_items.get(this).splice(i, 0, queueElement);added = truebreak}}if (!added) {_items.get(this).push(queueElement)}}dequeue() {return _items.get(this).shift()}front() {return _items.get(this)[0]}isEmpty() {return this.size === 0}size() {return _items.get(this).length}toString() {return _items.get(this)}}})()var a = new Queue()a.enqueue("张三", 1)a.enqueue("李四", 2)a.enqueue("赵六", 3)a.enqueue("熊七", 4)a.enqueue("赵八", 2)// a.dequeue()console.log(a.front())console.log(a.isEmpty())console.log(a.size())console.dir(a.toString())
链表
单向链表
// 链表class Node {constructor(element) {this.element = elementthis.next = null}}class LinkedList {constructor() {this.head = null;this.size = 0;}getNode(index) {if (index < 0 || index >= this.size) {throw new Error("out of range")}let current = this.headfor (var i = 0; i < index; i++) {current = current.next}return current}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++}appendAt(element, position) {let node = new Node(element)if (position === 0) {node.next = this.headthis.head = node} else {let pre = this.getNode(position - 1);node.next = pre.nextpre.next = node;}this.size++}indexOf(element) {let current = this.headfor (var i = 0; i < index; i++) {if (current.element === element) {return i}current = current.next}return -1}removeAt(position) {let current = this.headif (position === 0) {this.head = current.head} else {let pre = this.getNode(position - 1)current = pre.nextpre.next = current.next}this.size--}}let ll = new LinkedList()ll.append(1)ll.append(2)ll.append(3)ll.appendAt(4, 1)ll.removeAt(2)console.dir(ll, {depth: 1000})
