javascript數據結構與算法筆記(六):雙向鏈表

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"))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章