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 输出结果
写了 迭代器 所以可以用for of 输出
类提供的方法