function Node(data) {
this.data = data;
this.next = null;
}
function SingleList() {
this.head = null;
this.length = 0;
}
SingleList.prototype = {
// 查找节点
findElement: function(element) {
let head = this.head;
if (head === null) {
return '未找到元素';
}
while(head.data !== element) {
head = head.next;
}
return head;
},
// 查找最后一个节点
findLastElement: function() {
let head = this.head;
if (head === null) {
return '没有元素'
}
while(head.next !== null) {
head = head.next;
}
return head;
},
// 最后添加节点
pushElement: function(element) {
let newNode = new Node(element);
let head = this.head;
if (head === null) {
this.head = newNode;
} else {
while ( head.next !== null ) {
head = head.next;
}
head.next = newNode;
}
this.length++;
},
// 添加节点
insertElement: function(item, element) {
let searchNode = this.findElement(item);
let newNode = new Node(element);
if (searchNode) {
newNode.next = searchNode.next;
searchNode.next = newNode;
this.length++;
}
},
// 根据位置删除节点
removeAt: function(position) {
if (position < -1 && position >= length) return '索引不正确';
let head = this.head;
if (position === 0) {
this.head = head.next;
this.length--;
return;
}
while ( --position ) {
head = head.next;
}
head.next = head.next.next;
this.length--;
},
// 删除节点
removeElement: function(element) {
let removeNode = this.findElement(element);
if ( !removeNode ) return '节点不存在';
let head = this.head;
if (element === head.data) {
this.head = head.next;
this.length--;
return;
}
while (head.next.data !== element) {
head = head.next;
}
head.next = head.next.next;
this.length--;
},
// 查空
isEmpty: function() {
return this.length === 0;
},
// 查长度
getLen: function() {
return this.length;
},
// 清空
clear: function() {
this.head = null;
this.length = 0;
}
}
从上面我们可以看出我们针对链表的插入、删除操作,需要对插入第一个节点和删除最后一个节点左特殊的处理。这样处理起来确是繁琐,我们经常会因为忘记处理边界,而只是考虑正常情况程序能否工作而产生错误。
我们可以使用哨兵来简化实现难度(用来优化边界问题),在这个时候,不管链表是否为空,head 指针都会一直指向这个哨兵结点。我们就可以利用它来统一相同的代码逻辑。