1. 程式人生 > >javascript資料結構與演算法筆記(五):連結串列

javascript資料結構與演算法筆記(五):連結串列

javascript資料結構與演算法筆記(五):連結串列

一:簡介

連結串列儲存有序的元素集合,但不同於陣列,連結串列中的元素在記憶體中並不是連續放置的。每個
元素由一個儲存元素本身的節點和一個指向下一個元素的引用(也稱指標或連結)組成。
結構如下:
在這裡插入圖片描述

二:ES6版LinkedList類

1.LinkedList類宣告以及輔助類Node儲存節點資訊
如想使用WeakMap類宣告LinkedList類,具體原因可以參照:https://blog.csdn.net/wushichao0325/article/details/84969725

class Node{
    constructor(element){
         this.element=element;
         this.next=null;
     }
}
class LinkedList{
    constructor(){
        this.length=0;
        this.head=null;
    }
}

2.向連結串列尾部追加元素
向LinkedList物件尾部新增一個元素時,可能有兩種場景:列表為空,新增的是第一個元素,或者列表不為空,向其追加元素。即:
情況一:
在這裡插入圖片描述
情況二:
在這裡插入圖片描述

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.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;
        }else{
            while(index++<position){//找到position位置的前一個元素Node
                previous=current;
                current=current.next;//此時current指向的position位置的元素
            }
            //將前一個的next指標指向currrent即position位的next節點
            previous.next=current.next;
        }
        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){//在第一個位置插入
            node.next=current;
            this.head=node;
        }else{
            while(index++<position){
                previous=current;//記錄插入位置的前一個節點
                current=current.next;//記錄插入位置的節點
            }
            node.next=current;
            previous.next=node;
        }
        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 LinkedList();
linkedList.append("1");
linkedList.append("2");
console.log(linkedList.toString())
let result=linkedList.insert(2,"3");
console.log(result)
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"));