javascript資料結構與演算法筆記(六):雙向連結串列
阿新 • • 發佈:2018-12-27
javascript資料結構與演算法筆記(六):雙向連結串列
一:簡介
雙向連結串列和普通連結串列的區別在於,在連結串列中,一個節點只有鏈向下一個節點的連結,而在雙向連結串列中,連結是雙向的:一個鏈向下一個元素,另一個鏈向前一個元素
結構如下:
二:ES6版DoublyLinkedList類
1.DoublyLinkedList類宣告以及輔助類Node儲存節點資訊
如想使用WeakMap類宣告LinkedList類,具體原因可以參照:https://blog.csdn.net/wushichao0325/article/details/84969725
class Node{
constructor(element){
this.element=element;
this.next=null;//指向下一個
this.prev=null;//指向前一個
}
}
class DoublyLinkedList{
constructor(){
this.length=0;
this.head=null;
this.tail=null;
}
}
2.向連結串列尾部追加元素
append(element){
let node=new Node(element);
let current;
if(this.head==null){//如果插入的元素為頭節點
this.head=node;
}else{
current=this.head;
//迴圈列表,知道找到最後一項
while(current.next){
current=current.next;
}
//找到最後一項,讓最後一項的next指向將要新增的元素
current.next=node;
this.tail=node;
}
this.length++;//記錄列表的最新長度
}
3.從連結串列中移除元素
移除元素也有兩種場景:第一種是移除第一個元素,第二種是移除最後一個元素,第三種是移除中間的任一元素
情況一:
情況二:
情況三:
removeAt(position){
//檢測傳入的position是否越界
if(position>-1&&position<this.length){
let current=this.head;
let previous;//記錄前一個元素
let index=0;
if(position==0){//移除第一項
this.head=current.next;
//如果只有一項,更新tail
if(this.length==1){
this.tail=null;
}else{
this.head.prev=null;
}
}else if(position==this.length-1){//最後一項
current=this.tail;
this.tail=current.prev;
this.tail.next=null;
}else{
while(index++<position){//找到position位置的前一個元素Node
previous=current;
current=current.next;//此時current指向的position位置的元素
}
//將前一個的next指標指向currrent即position位的next節點
previous.next=current.next;
current.next.prev=previous;
}
this.length--;
return current.element;//返回移除的position位的元素資訊
}else{
return null;
}
}
4.在任意位置插入元素
任意位置插入元素也有兩種場景:第一種是在列表的起點新增一個元素,第二種是在列表的末尾新增一個元素,第三種是在列表中間或尾部新增一個元素。
情景一:
情景二:
情景三:
insert(position,element){
if(position>=0&&position<=this.length){//==this.length保證可以往隊尾插入
let node=new Node(element),
current=this.head,
previous,
index=0;
if(position==0){//在第一個位置插入
if(!this.head){
this.head=node;
this.tail=node;
}else{
node.next=current;
current.prev=node;
this.head=node;
}
}else if(position==this.length){//末尾
current=this.tail;
console.log("current:",current)
current.next=node;
node.prev=current;
this.tail=node;
}else{
while(index++<position){
previous=current;//記錄插入位置的前一個節點
current=current.next;//記錄插入位置的節點
}
node.next=current;
previous.next=node;
current.prev=node;
node.prev=previous;
}
this.length++;//更新連結串列的長度
return true;
}else{
return false;
}
}
5.列印連結串列
toString方法會把LinkedList物件轉換成一個字串
toString(){
let current=this.head;
let string='linklist:';
while(current){
string+=current.element+(current.next?'->':'');
current=current.next;
}
return string;
}
6.查詢指定元素是否存在
indexOf方法接收一個元素的值,如果在列表中找到
它,就返回元素的位置,否則返回-1。
indexOf(element){//查詢指定的元素是否存在在連結串列中
let current=this.head;
let index=-1;
while(current){
index++;
if(element==current.element){
return index;
}
current=current.next;
}
return -1;
}
7.isEmpty、size、getHead方法
isEmpty(){
return this.length==0;
}
size(){
return this.length;
}
getHead(){
return this.head;
}
8.刪除指定元素
remove(element){
let index=this.indexOf(element);
return this.removeAt(index);
}
9.使用連結串列
let linkedList=new DoublyLinkedList();
linkedList.append("1");
linkedList.append("2");
console.log(linkedList.toString())
let result=linkedList.insert(2,"3");
console.log(linkedList.toString())
// console.log(linkedList.toString());
linkedList.remove("2");
console.log(linkedList.toString());
console.log(linkedList.indexOf("1"));
// linkedList.removeAt(0);
// console.log(linkedList.toString());
// console.log(linkedList.indexOf("1"))