- 单向链表只能从从遍历到尾,缺点是可以轻松到达下一个节点,但是很难回到上一个节点
- 双向链表可以从头遍历到尾,也可以从尾遍历到头,一个节点既有向前的引用,也有向后的引用
- 双向链表结构
- 双向链表方法
- append(element):向列表尾部添加一个新的项
- insert(position,element):向列表的特定位置插入一个新的项。
- get(position):获取对应位置的元素
- indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。
- update(position,element):修改某个位置的元素
- removeAt(position):从列表的特定位置移除一项。
- remove(element):从列表中移除一项。
- isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false.
- size():返回链表包含的元素个数。与数组的length属性类似。
- toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值。
- forwardString():返回正向遍历的节点字符串形式
- backwordString():返回反向遍历的节点字符串形式
- 封装双向链表
function DoubleLinkedList(){
function Node(data){
this.data = data;
this.pre = null;
this.next = null;
}
this.head = null;
this.tail = null;
this.length = 0 ;
DoubleLinkedList.prototype.append = function(data){
var newNode = new Node(data);
if(this.length === 0){
this.head = newNode;
this.tail = newNode;
}else{
newNode.pre = this.tail;
this.tail.next = newNode;
this.tail = newNode;
}
this.length += 1;
}
DoubleLinkedList.prototype.insert = function(position,data){
if(position < 0 || position > this.lengh) return false;
var newNode = new Node(data);
if(this.length === 0){
this.head = newNode;
this.tail = newNode;
}else{
if(position === 0){
this.head.pre = newNode;
newNode.next = this.head;
this.head = newNode;
}else if(position = this.length){
newNode.pre = this.tail;
this.tail.next = newNode;
this.tail = newNode;
}else{
var current = this.head;
var index = 0
while(index++ < position){
current = current.next;
}
newNode.next = current;
newNode.pre = current.pre;
current.pre.next = newNode;
current.pre = newNode;
}
}
this.length += 1;
return true;
}
DoubleLinkedList.prototype.get = function(position){
if(position < 0 || position >=this.length) return false;
var current = this.head;
var index = 0;
while(index++ < position){
current = current.next;
}
return current.data;
}
DoubleLinkedList.prototype.indexOf = function(data){
var current = this.head;
var index = 0;
while(current){
if(current.data === data){
return index;
}else{
current = current.next;
index++;
}
}
return -1;
}
DoubleLinkedList.prototype.update = function(position){
if(position < 0 || position >=this.length) return false;
var current = this.head;
var index = 0;
while(index++ < position){
current = current.next;
}
current.data = data;
}
DoubleLinkedList.prototype.removeAt= function(position){
if(position < 0 || position >=this.length) return null;
var current = this.head;
var index = 0 ;
if(this.length === 1){
this.head = null;
this.tail = null;
}else{
if(position === 0){
this.head.next = null;
this.head = this.head.next;
}else if(position === this.length-1){
current = this.tail;
this.tail.pre.next = null;
this.tail = this.tail.pre;
}else{
while(index++ < position){
current = current.next;
}
current.pre.next = current.next;
current.next.pre = current.pre;
}
}
this.length -= 1;
return current.data
}
DoubleLinkedList.prototype.remove = function(){
var index = this.indexOf(data);
return this.removeAt(index);
}
DoubleLinkedList.prototype.ieEmpty = function(){
return this.length === 0 ;
}
DoubleLinkedList.prototype.size = function(){
return this.length;
}
DoubleLinkedList.prototype.getHead = function(){
return this.head.data;
}
DoubleLinkedList.prototype.getTail = function(){
return this.tail.data;
}
DoubleLinkedList.prototype.toString = function(){
return this.backwardString();
}
DoubleLinkedList.prototype.toString = function(){
return this.backwardString();
}
DoubleLinkedList.prototype.forwardString = function(){
var current = this.tail;
var resultString = null;
while(current){
resultString += current.data + " ";
current = current.pre
}
return resultString;
}
DoubleLinkedList.prototype.backwardString = function(){
var current = this.head;
var resultString = '';
while(current){
resultString += current.data + " ";
current =current.next;
}
return resultString;
}
}