类 实现简单链表

80 阅读1分钟

js类 实现链表

可以用对象的形式存储数据 数据的排序可以按照自己的意愿排序

创建LinkedMap.js


class Node {
	constructor(key, val) {
		this.key = key || "_root";
		this.val = val || "_root";
		this.pin = false;
		this.prev = null;
		this.next = null;
	}
}

class LinkedHashMapIterator {
	constructor(map) {
		this.map = map;
		this.node = map._root.next;
	}

	next() {
		if (this.node == null) {
			return {
				value: null,
				done: true
			}
		}
		let result = {
			value: this.node.val,
			done: false
		}
		this.node = this.node.next;
		return result;
	}
}

class LinkedHashMap {
	constructor() {
		this._size = 0;
		this._root = new Node();
	}

	put(key, value, callback) {
		let node = this.getNode(key);
		if (node) {
			node.val = value;
			if (callback) {
				callback.call(this, node);
			}
			return node;
		}
		let lastNode = this.lastNode();
		node = new Node(key, value);
		lastNode.next = node;
		node.prev = lastNode;
		this._size++;
		if (callback) {
			callback.call(this, node);
		}
		return node;
	}

	putOrPinUnderTop(key, value) {
		let node = this.getNode(key);
		if (node == null) {
			node = new Node(key, value);
		} else {
			node = this.put(key, value);
		}
		if (node.pin) {
			this._insertAfter(node, this._root);
			return
		}
		let lastPinNode = this._getLastPinNode();
		if (lastPinNode == null) {
			lastPinNode = this._root;
		}
		this._insertAfter(node, lastPinNode);
		return;
	}


	get(key) {
		let node = this.getNode(key);
		if (node == null) {
			return null;
		}
		return node.val;
	}

	_getLastPinNode() {
		let node = this._root.next;
		while (node) {
			if (node.pin == true && node.next && node.next.pin == false) {
				return node;
			}
			node = node.next;
		}
		return null;
	}

	remove(key) {
		let node = this.getNode(key);
		if (!node) return;
		node.prev.next = node.next;
		if (node.next) {
			node.next.prev = node.prev;
		}
		this._size--;
	}

	getNode(key) {
		let node = this._root;
		while (node) {
			if (node.key == key) {
				return node;
			}
			node = node.next;
		}
	}

	_insertAfter(node, beforeNode) {
		// 先移除Node
		this.remove(node.key);
		node.next = beforeNode.next;
		if (beforeNode.next) {
			beforeNode.next.prev = node;
		}

		beforeNode.next = node;
		node.prev = beforeNode;
		this._size++;

	}

	_insertBefore(node, afterNode) {
		this.remove(node.key);
		afterNode.prev.next = node;
		node.prev = afterNode.prev;
		node.next = afterNode;
		afterNode.prev = node;
		this._size++;
	}

	lastNode() {
		let node = this._root;
		while (node.next) {
			node = node.next;
		}
		return node;
	}

	forEach(callback) {
		let node = this._root.next;
		while (node) {
			callback.call(null, node.key, node.val, node);
			node = node.next;
		}
	}

	pin(key) {
		let target = this.getNode(key);
		this._insertAfter(target, this._root);
		target.pin = true;
	}

	unpin(key) {
		if (this._size == 0) {
			return;
		}
		let target = this.getNode(key);
		if (this._size == 1) {
			target.pin = false;
			return;
		}
		let node = this._root.next;
		let firstNode = this._root.next == target ? target.next : this._root.next;;
		if (firstNode.pin == true) {
			this.remove(key);
			while (node) {
				if (node.pin == true && (node.next == null || node.next.pin == false)) {
					target.next = node.next;
					if (target.next) {
						target.prev = target;
					}
					target.prev = node;
					node.next = target;

					target.pin = false;
					this._size++;
					return;
				}
				node = node.next;
			}
		}
		target.pin = false;
	}

	[Symbol.iterator]() {
		return new LinkedHashMapIterator(this);
	}
}

导入LinkedMap.js<script src="./LinkedMap.js"></script> new

  <script>
    var map = new LinkedHashMap();
    map.put("aaa", 111);
    map.put("bbb", 222);
    map.put("ccc", 333);
  </script>

控制台调用类forEach 输出结果 QQ截图20220907095452.png

写了 迭代器 所以可以用for of 输出 QQ截图20220907095739.png

类提供的方法 $_M)D%[_TC](Q}J[VMA7]Q4.png