一、单链表构造函数
function LinkedList() { /** * 数据节点构造函数 * * @param {*} data */ function Node(data) { this.data = data; this.next = null; } let length = 0; let head = null; let tail = null; /** * 链表尾部追加数据 * * @param {*} item */ this.append = function (item) { const newNode = new Node(item); if (0 < length) { tail.next = newNode; tail = newNode; } else { head = tail = newNode; } length++; }; /** * 在指定索引位置的前面插入数据 * * @param {number} index 指定的索引位置 * @param {*} item * @returns {boolean} 返回是否成功 */ this.insert = function (index, item) { if (0 <= index && index <= length) { const newNode = new Node(item); if (0 < index && index < length) { // 在中间添加 let prevNode = null; let targetNode = head; let prevIndex = 0; while ((prevIndex++) < index) { prevNode = targetNode; targetNode = targetNode.next; } prevNode.next = newNode; newNode.next = targetNode; } else if (0 === index) { // 在头部添加 newNode.next = head; head = newNode; } else { // 在尾部添加 this.append(item); } length++; return true; } else { return false; } }; /** * 删除指定索引位置处的数据项。发生错误将throw一个Error * * @param {number} index 指定的索引位置 * @returns {*} 返回被删除的数据 */ this.remove = function (index) { if (0 <= index && index < length) { let targetNode; if (0 < index) { // 删除非头部 let prevNode = null; targetNode = head; let prevIndex = 0; while ((prevIndex++) < index) { prevNode = targetNode; targetNode = targetNode.next; } prevNode.next = targetNode.next; targetNode.next = null; // 如果删除的是最后一个,把tail指向倒数第二个 if ((1 + index) === length) { tail = prevNode; } } else if (0 === index) { targetNode = head; // 删除头部 const nextNode = targetNode.next; targetNode.next = null; head = nextNode; } length--; return targetNode.data; } else { throw new RangeError(`out of range: must between 0 and ${length}`); } }; /** * 查找数据项在链表中的索引位置 * * @param {*} item * @returns {number} 索引位置,不存在则返回-1 */ this.indexOf = function (item) { let prevIndex = 0; let targetNode = head; while (!!targetNode) { if (item !== targetNode.data) { targetNode = targetNode.next; prevIndex++; } else { return prevIndex; } } return -1; }; /** * 顺序打印出链表中的所有节点数据 * */ this.print = function () { let index = 0; let targetNode = head; while (!!targetNode) { console.log('[', index++, ']=>', targetNode.data); targetNode = targetNode.next; } }; /** * 查找单链表中的第K个节点 * * @param {number} index 索引位置 * @returns {*} index位置的数据 */ this.findByIndex = function (index) { if (0 <= index && index < length) { let targetNode = head; while (0 < (index--)) { targetNode = targetNode.next; } return targetNode.data; } else { throw new RangeError(`out of range: must between 0 and ${length}`); } }; /** * 查找单链表的中间位置的节点 * * @returns {*} index位置的数据 */ this.findMiddle = function () { const index = Math.round(length / 2) - 1; return this.findByIndex(index); }; }
二、实现双向链表的构造函数
function DoubleLinkedList() { let length=0, head=null, tail=null; /** * 数据节点构造函数 * * @param {*} data */ function Node(data) { this.data=data; this.next=null; this.previous=null; } /** * 链表尾部追加数据 * * @param {*} item */ this.append = function (item) { let newNode=new Node(item); //空链表 if(null===head){ head=newNode; tail=head; }else{ tail.next=newNode; tail=newNode; } length++; }; /** * 在指定索引位置的前面插入数据 * * @param {number} index 指定的索引位置 * @param {*} item */ this.insert = function (index, item) { let newNode=new Node(item), current=head, previous=null, insetIndex=0; if(index < 0 || index > length){ return false }else { //在第一个位置添加 if(0 === index){ newNode.next=current; current.previous=newNode; head=newNode }else if(index === index){ //在末尾添加 current=tail; current.next=newNode; newNode.previous=current; tail=newNode; }else { while (insetIndex < index){ previous=current; current=current.next; insetIndex++; } previous.next=newNode; newNode.previous=previous; newNode.next=current; current.previous=newNode; } length++; } }; /** * 删除指定索引位置处的数据项 * * @param {number} index 指定的索引位置 */ this.remove = function (index) { if (0 <= index && index < length) { let targetNode; if (0 < index) { // 删除非头部 let prevNode = null; targetNode = head; let prevIndex = 0; while ((prevIndex++) < index) { prevNode = targetNode; targetNode = targetNode.next; } prevNode.next = targetNode.next; if (!!targetNode.next) { targetNode.next.prev = prevNode; } targetNode.prev = null; targetNode.next = null; // 如果删除的是最后一个,把tail指向倒数第二个 if ((1 + index) === length) { tail = prevNode; } } else if (0 === index) { targetNode = head; // 删除头部 const nextNode = targetNode.next; nextNode.prev = null; head = nextNode; targetNode.next = null; } length--; return targetNode.data; } else { throw new RangeError(`out of range: must between 0 and ${length}`); } }; /** * 顺序打印出链表中的所有节点数据 * */ this.print = function () { console.log('顺序打印'); let index = 0; let targetNode = head; while (!!targetNode) { console.log('[', index++, ']=>', targetNode.data); targetNode = targetNode.next; } }; /** * 逆序打印出链表中的所有节点数据 * */ this.reversePrint = function () { console.log('逆序打印'); let index = length - 1; let targetNode = tail; while (!!targetNode) { console.log('[', index--, ']=>', targetNode.data); targetNode = targetNode.prev; } }; }