/*
@author: leeenx
@链表结构
*/
class Chain {
constructor(datas = []) {
// 三个指针
this.HEAD = this.TAIL = this.POINTER = null;
// 前驱
this.NEXT = "next";
// 后继
this.PREV = "prev";
// 链表长度
this.length = 0;
// 初化数据
this.push(...datas);
}
// 创建链表节点
generateNode(data) {
// 匿名对象做节点
return {
data: data,
next: null,
prev: null
}
}
// 向尾部插入节点
push(...datas) {
// 前驱后继
let {NEXT, PREV} = this;
datas.forEach((data) => {
// 节点
let node = this.generateNode(data), TAIL = this.TAIL;
// 前驱后继指定
if(null !== TAIL) {
[TAIL[NEXT], node[PREV]] = [node, TAIL];
}
// 尾指针指向当前节点
this.setTail(node);
// 链表长度增加1
++this.length;
});
return true;
}
// 向头部插入节点
unshift(...datas) {
// 前驱后继
let {NEXT, PREV} = this;
datas.forEach((data) => {
// 节点
let node = this.generateNode(data), HEAD = this.HEAD;
// 前驱后继指定
if(null !== HEAD) {
[HEAD[PREV], node[NEXT]] = [node, HEAD];
}
// 头指针指向当前节点
this.setHead(node);
// 链表长度增加1
++this.length;
});
return true;
}
// 从尾部删除节点,并返回它的data
pop() {
if(this.length === 0) return false;
// 前驱后继, 头尾指针,普通指针
let {NEXT, PREV, HEAD, TAIL, POINTER, TAIL: {data}} = this, newTail = TAIL[PREV];
// 只有一个节点或没有节点,清空HEAD&TAIL&POINTER
if(TAIL === HEAD) {
this.setHead() & this.setTail() & this.setPointer();
}
// 尾指针后移一位
else {
// 当前指针指向尾节点,向后移一位
TAIL === POINTER && this.setPointer(newTail);
// 尾指针向后移一位
this.setTail(newTail);
// 删除旧的尾节点与当前尾节点的前驱
[TAIL, newTail[NEXT]] = [null, null];
}
// 链表长度减少1
--this.length;
return data;
}
// 从头部删除节点,并返回它的data
shift() {
if(this.length === 0) return false;
// 前驱后继, 头尾指针,普通指针
let {NEXT, PREV, HEAD, TAIL, POINTER, HEAD: {data}} = this, newHead = HEAD[NEXT];
// 只有一个节点或没有节点,清空HEAD&TAIL&POINTER
if(TAIL === HEAD) {
this.setHead() & this.setTail() & this.setPointer();
}
// 头指针前移一位
else {
// 当前指针指向头节点,向前移一位
HEAD === POINTER && this.setPointer(newHead);
// 头指针向前移一位
this.setHead(newHead);
// 删除旧的头节点与当前头节点的后继
[HEAD, newHead[PREV]] = [null, null];
}
// 链表长度减少1
--this.length;
return data;
}
// 返回指定索引节点的 data, 并把POINTER指向当前位置
at(index = 0) {
if(index < 0 || index >= this.length) return false;
// 指针回调至头部
this.setPointer();
// 前驱后继, 头指针,普通指针
let {NEXT, PREV, HEAD, POINTER} = this, cur = POINTER;
while(0 < index--) {
cur = cur[NEXT]
}
// 指针指向cur
this.setPointer(cur);
return cur.data;
}
// 返回当前节点的data,并把POINTER向前移一位
next() {
if(this.length === 0) return false;
// 前驱后继, 普通指针
let {NEXT, PREV, POINTER, POINTER: {data}} = this, newPointer = POINTER[NEXT];
this.setPointer(newPointer);
return data;
}
// 返回当前节点的data,并把POINTER向后移一位
prev() {
if(this.length === 0) return false;
// 前驱后继, 普通指针
let {NEXT, PREV, POINTER, POINTER: {data}} = this, newPointer = POINTER[PREV];
this.setPointer(newPointer);
return data;
}
// 返回当前节点的data
curr() {
return this.POINTER.data;
}
// 返回头节点的data
first() {
if(this.length === 0) return false;
return this.HEAD.data;
}
// 返回尾节点的data
last() {
if(this.length === 0) return false;
return this.TAIL.data;
}
// 在指定索引前插入节点
insertBefore(index, ...datas) {
if(this.length === 0 || index >= this.length) return false;
// 定位到 index 位置
this.at(index);
// 前驱后继,普通指针
let {NEXT, PREV, POINTER} = this, currNode = POINTER;
datas.forEach((data) => {
let node = this.generateNode(data), prevNode = currNode[PREV];
// 前驱后继指定
[currNode[PREV], node[NEXT], node[PREV]] = [node, currNode, prevNode];
// 前驱节点非指向HEAD,前驱节点的NEXT指向新节点
if(prevNode !== null) {
prevNode[NEXT] = node;
}
// 前驱节点指向HEAD,头指针更新为当前节点
else {
this.setHead(node);
}
// 链表长度增加1
++this.length;
});
return true;
}
// 在指定索引前插入链表
insertChainBefore(index, chain) {
// 索引超标
if(index >= this.length) return false;
// 主链为空,直接引用子链表 chain
if(this.length === 0) {
this.setHead(chain.HEAD);
this.setTail(chain.TAIL);
this.setPointer(chain.POINTER);
}
// 非空主链
else {
// 定位到 index 位置
this.at(index);
let {NEXT, PREV, POINTER} = this, node = POINTER, prevNode = node[PREV];
// index 位置元素后驱指定
[chain.HEAD[PREV], chain.TAIL[NEXT], node[PREV]] = [prevNode, node, chain.TAIL];
// 前驱节点非指向HEAD,前驱节点的NEXT指向 chain.HEAD
if(prevNode !== null) {
prevNode[NEXT] = chain.HEAD;
}
// 前驱节点指向HEAD,头指针更新为 chain.HEAD
else {
this.setHead(chain.HEAD);
}
}
// 链表长度更新
this.length += chain.length;
}
// 在指定索引后插入节点
insertAfter(index, ...datas) {
if(this.length === 0 || index >= this.length) return false;
// 定位到 index 位置
this.at(index);
// 前驱后继,普通指针
let {NEXT, PREV, POINTER} = this, currNode = POINTER;
datas.forEach((data) => {
let node = this.generateNode(data), nextNode = currNode[NEXT];
// 前驱后继指定
[currNode[NEXT], node[PREV], node[NEXT]] = [node, currNode, nextNode];
// 后继节点非指向TAIL,后继节点的PREV指向新节点
if(nextNode !== null) {
nextNode[PREV] = node;
}
// 后继节点指向TAIL,尾指针更新为当前节点
else {
this.setTail(node);
}
// 保持datas的插入顺序
currNode = node;
// 链表长度增加1
++this.length;
});
return true;
}
// 在指定索引后插入链表
insertChainAfter(index, chain) {
// 索引超标
if(index >= this.length) return false;
// 主链为空,直接引用子链表 chain
if(this.length === 0) {
this.setHead(chain.HEAD);
this.setTail(chain.TAIL);
this.setPointer(chain.POINTER);
}
// 非空主链
else {
// 定位到 index 位置
this.at(index);
let {NEXT, PREV, POINTER} = this, node = POINTER, nextNode = node[NEXT];
// index 位置元素后驱指定
[chain.HEAD[PREV], chain.TAIL[NEXT], node[NEXT]] = [node, nextNode, chain.HEAD];
// 后继节点非指向TAIL,后继节点的PREV指向 chain.TAIL
if(nextNode !== null) {
nextNode[PREV] = chain.TAIL;
}
// 后继节点指向TAIL,尾指针更新为 chain.TAIL
else {
this.setTail(chain.TAIL);
}
}
// 链表长度更新
this.length += chain.length;
}
// 删除指定索引的节点,并节点的 data
remove(index) {
if(index >= this.length || this.length === 0) return false;
let data = this.at(index), {NEXT, PREV, HEAD, TAIL, POINTER} = this, currNode = POINTER;
// 删除头节点
if(HEAD === POINTER) {
this.shift();
}
// 删除尾节点
else if(TAIL === POINTER) {
this.pop();
}
// 中间节点
else {
let prevNode = currNode[PREV], nextNode = currNode[NEXT];
[prevNode[NEXT], currNode, nextNode[PREV]] =[nextNode, null, prevNode];
// 修改指针指向
this.POINTER = nextNode;
// 链表长度减少1
--this.length;
}
return data;
}
// clone
clone() {
let cp = new this.constructor();
for(let data of this) {
cp.push(data);
}
return cp;
}
// 快速反转
reverse() {
[this.HEAD, this.TAIL, this.NEXT, this.PREV] = [this.TAIL, this.HEAD, this.PREV, this.NEXT];
return true;
}
// 排序
sort(compare) {
// 快速排序函数
let quickSort = (node, len, compare = (a, b) => a - b) => {
// 基点 node
let pivot = node,
// 计数
count = 0,
// 左侧节点长度,默认为1
leftLen = 1,
// 当前片段的最左侧节点
leftNode;
while(++count < len) {
node = node.next;
// 当前元素大于基点值,转移到基点左侧
if(compare(pivot.data, node.data) > 0) {
// node 的前驱与后续
let next = node.next, prev = node.prev;
// 移除 node
if(next !== null) {
// 非尾节点
[next.prev, prev.next] = [prev, next];
}
else {
// 尾节点
prev.next = next;
this.setTail(prev);
}
// 在 pivot 前插入 node
if(pivot.prev !== null) {
// pivot 非头节点
[pivot.prev.next, pivot.prev, node.prev, node.next] = [node, node, pivot.prev, pivot];
}
else {
// 头节点
[pivot.prev, node.prev, node.next] = [node, pivot.prev, pivot];
this.setHead(node);
}
// 最左侧节点标记
leftNode === undefined && (leftNode = node);
// 左侧节点增加1
++leftLen;
// node 回退到后继
node = prev;
}
}
// 分割后递归
leftLen > 1 && quickSort(leftNode, leftLen, compare);
len - leftLen > 1 && quickSort(pivot.next, len - leftLen, compare);
}
// 链表指针回退至头部
quickSort(this.HEAD, this.length, compare);
}
// 索引
indexOf(data, fromIndex = 0) {
this.at(fromIndex);
let targetIndex = fromIndex;
while(this.TAIL !== this.POINTER) {
let curData = this.next();
if(curData === data) {
return targetIndex;
}
++targetIndex;
}
return -1;
}
// 克隆链表的一段切片
slice(start = 0, end) {
let sliceChain = new this.constructor();
if(start >= 0 && end > start) {
// 限制end
end = Math.min(end, this.length);
this.at(start);
while(start++ !== end) {
sliceChain.push(this.next());
}
}
return sliceChain;
}
// 拼接chain链,并返回被删除部分
splice(start, deleteCount, ...datas) {
if(start < 0 || start >= this.length) return false;
deleteCount = Math.min(this.length - start, deleteCount);
let removedChain = new this.constructor();
// 删除节点
while(deleteCount--) {
removedChain.push(this.remove(start));
}
// 插入节点
this.insertBefore(start, ...datas);
return removedChain;
}
// 合并两条 chain
concat(chain) {
if(chain !== undefined && chain.length !== 0) {
// NEXT/PREV 指向不同步
if(this.NEXT !== chain.NEXT) {
// 不同步,需要用 push 完成
for(let data of chain) {
this.push(data);
}
}
// NEXT, PREV 同步,可以快速合并
else {
let {NEXT, PREV, HEAD, TAIL} = this;
// 空链表
if(HEAD === TAIL === null) {
this.setHead(chain.HEAD) & this.setTail(chain.TAIL) & setPointer();
}
// 非空链表
else {
let [headA, tailA, headB, tailB] = [this.HEAD, this.TAIL, chain.HEAD, chain.TAIL];
// 尾指针指向新链表的尾指针
this.TAIL = chain.TAIL;
// A链的尾结点[NEXT]指向B的头节点,B链的头结点[PREV]指向A的尾结点。完成串合
[tailA[NEXT], headB[PREV]] = [headB, tailB];
// 长度合并
this.length += chain.length;
}
}
}
return this;
}
// 指定头指针
setHead(node = null) {
this.HEAD = node;
// 如果尾指针未指定,头尾指针同指向node
this.TAIL === null && this.setTail(node) & this.setPointer(node);
}
// 指定尾指针
setTail(node = null) {
this.TAIL = node;
// 如果头指针未指定,头尾指针同指向node
this.HEAD === null && this.setHead(node) & this.setPointer(node);
}
// 指定指针
setPointer(node = this.HEAD) {
this.POINTER = node;
}
// 创建一个迭代接口
[Symbol.iterator]() {
let that = this;
// POINTER 指向 HEAD
this.setPointer();
return (function* () {
while(that.POINTER !== null) {
yield that.next();
}
// 指针停在最后一位
that.POINTER = that.TAIL;
}());
}
}
console