一、单链表构造函数
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;
}
};
}