JavaScript數據結構與算法——鏈表

1.鏈表數據結構

鏈表存儲有序的元素集合,但不同於數組,鏈表中的元素咋內存中並不是連續放置的每個元素有一個存儲元素本身的節點和一個指向下一個元素的引用組成。下圖展示了一個鏈表的結構:
clipboard.png
鏈表的優點:
鏈表是很常用的一種數據結構,不需要初始化容量,可以任意加減元素;
添加或者刪除元素時只需要改變前後兩個元素結點的指針域指向地址即可,所以添加,刪除很快;

缺點:
因爲含有大量的指針域,佔用空間較大;
查找元素需要遍歷鏈表來查找,非常耗時。

適用場景:
數據量較小,需要頻繁增加,刪除操作的場景

2.創建鏈表

function LinkedList() {
    // 創建一個node類,表示將要加入的項 element表示要添加的值,next指向列表中下一個節點項的指針
    let Node = function(element) {
        this.element = element;
        this.next = null;
    }
    let length = 0;
    let head = null;
    // 下面聲明鏈表的方法
    // 1.向列表尾部添加一個新的項
    this.append = function(element) {
        let node = new Node(element);
            current;
        // 列表爲空,添加的是第一個元素
        if(head === null) {
           head = node; 
        // 列表不爲空,向其追加   
        } else {
           
            current = head;
            // 循環列表,直到找到最後一項
            while(current.next) {
                current = current.next;
            }
            // 找到最後一項,將其next賦爲node,建立鏈接
            current.next = node;
        }
        // 更新列表長度
        length++;
    }
    // 2.從列表中移除元素
    this.removeAt = function(position) {
        // 檢查position是否超出鏈表範圍
        if(position > -1 && position < length) {
            let current = head,
                previous,
                index = 0;
            // 移除第一個元素
            if(position === 0 ) {
                head = current.next;
            } else {
                // 循環到指定位置,找到該位置的 previous和current
                while(index++ < position) {
                    previous = current;
                    current = current.next;
                }
                // 將previous與current的下一項鍊接起來:跳過current
                previous.next = current.next;
            }    
            // 鏈表長度減一
            length--;
            // 返回被刪除項
            return current.element;
        } else {
            // 不是有效位置,返回null
            return null
        }
    }
     // 3.在任意位置插入元素
    this.insert = function(element, position) {
        //判斷是否超過鏈表範圍
        if (position >= 0 && position<= length) {
            let node = new Node(element),
                current = head,
                previous,
                index = 0;
            // 在首位插入元素
            if (position === 0 ) {
                node.next = current;
                head = node;
            } else{
                // x循環到position應該添加的位置,取出previous和current
                while(index++ < position) {
                    previous = current;
                    current = current.next;
                }
                // 在previous和current間插入
                node.next = current;
                previous.next = node;
            };    
            // 更新鏈表長度
            length++;
            return true;
        } else{
            return false;
        };
    }
    //4. 把LinkedList對象轉化成字符串
    this.toString = function() {
        let current = head,
            string = '';
        while(current) {
            string += current.element + (current.next ? 'n' : '');
            current = current.next;
        }  
        return string;  
    }
    //5.鏈表中是否存在某個值
    this.indexOf = function(element) {
        let current = head,
            index = 0;
        while(current) {
            if(element === current.element) {
                return index;
            }
            index++;
            current = current.next;
        }  
        return -1; 
    } 
    //6.通過element實現remove元素
    this.remove = function(element) {
        let index = this.indexOf(element);
        return this.removeAt(index);
    }
    //7.isEmpty size getHead方法
    this.isEmpty = function() {
        return length === 0; 
    }
    this.size = function() {
        return length;
    }
    this.getHead = function() {
        return head;
    }    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章