[我的心得]數據結構之單鏈表

維基百科node

  • 鏈表是一種常見的基礎數據結構,是一種線性表,可是並不會按線性的順序存儲數據,而是在每個節點裏存到下一個節點的指針。
  • 鏈表中最簡單的一種是單向鏈表,它包含兩個域,一個信息域和一個指針域。這個連接指向列表中的下一個節點,而最後一個節點則指向一個空值。
  • 一個單向鏈表包含兩個值: 當前節點的值和一個指向下一個節點的連接
  • 通常查找一個節點的時候須要從第一個節點開始每次訪問下一個節點,一直訪問到須要的位置。

2017031911565346.png


從上面能夠得知:git

  • 單鏈表的每個節點裏面有一個信息域(element)和一個指向下一個節點的指針(next)。
  • 查找一個節點是從第一個節點(head)找起。

那先建立節點的類吧:github

class Node {
  constructor (element) { //傳入數據
    this.element = element;
    this.next = null; //next是指向下一個節點的指針。
  }
}

接着建立單鏈表的類:數組

class SingleLinkedList {
  constructor () {
    this.head = null; // head指向第一個節點的指針。
    this.length = 0;
  }
}

給單鏈表增長一些方法(如下的方法都是寫在單鏈表類裏面的)數據結構

  • Append (加入一個節點)
/**
   * @param element 一個數據,能夠是任何的數據類型.
   */
append (element) {
    let node = new Node(element), // 實例化一個節點。
        current;                 

    if (!this.head) {             // 若是爲空則爲空鏈表
      this.head = node;           // 鏈表頭(head)指向第一個節點node。
    } else { // 不是空鏈表
      current = this.head;       // current也指向了第一個節點(用來從頭部開始進行操做,且爲了避免改變head的指向)
      while (current.next) {     // 循環,直到某個節點的next爲null
        current = current.next;  // 若是當前節點(current)的next不爲null,那麼current.next這個指針就給了current。
      }
      current.next = node;       //current.next爲null退出循環(即已到了最後一個節點),那麼它的next爲node
    }
    this.length++;               //加入節點後,要把單鏈表長度加一。
    console.log('Append successfully');
}
  • InsertNode(在某位置加入一個節點)
/**
   * @param element 一個數據,能夠是任何的數據類型.
   * @param {Number} position 要插入的某個位置. 
   */
  insertNode (element, position) {
    if (position >= 0 && position <= this.length) { // 判斷插入的位置。
      let node = new Node(element),
        current = this.head,          // current是指向第一個借點咯。
        previous,                     // 指向前一個節點的指針。
        index = 0;

      if (position === 0) {
        node.next = current;         //此時head的指向的節點,變爲了node指向的節點
        this.head = node;            // 而head固然指向node咯
      } else {
        while (index++ < position) { // index是不是要插入的位置,不是就+1。
          previous = current;        // 不是當前位置,那麼current這個指針就交給previous。
          current = current.next;    // 這個跟append方法同樣的。
        }                            // 是當前位置啦,就退出循環。
        previous.next = node;        // 前一個節點的next指向node(插入的節點)
        node.next = current;         // node.next就是current啦。
      }
      this.length++;
      console.log('Insert successfully');
    } else {
      throw new Error('這個單鏈表中不能從這個位置加入節點');
    }
  }
  • RemoveNode (刪除一個節點)
/** 
   * @param {Number} position 要刪除節點的位置
   */
  removeNode (position) {
    if (position > -1 && position < this.length) { //判斷是否存在這position。
      let current = this.head,         // 同上面同樣,用current來循環。
        previous,
        index = 0;

      if (position === 0) {
        this.head = current.next;     //head變爲指向下一個節點。
      } else {
        while (index++ < position) {  //判斷是否爲當前的位置。
          previous = current;         // current就變爲前一個節點 (指針變化)。
          current = current.next;     
        }                             // 肯定要刪除節點的位置,退出循環。
        previous.next = current.next; // 當前節點爲current,那麼移除它,這時前一個的節點就和後一個節點連在一塊兒咯。
      }
      this.length--;                  // 長度減一。
      console.log('Remove successfully');
    } else {
      throw new Error('單鏈表沒這個節點哦。');
    }
}
  • Print (輸出單鏈表的每一個節點)
print () {
    let arr = [this.head];  // 我用了數組包住了每一個節點。
    let node = this.head;
    while (node.next) {     // 下一個節點是否存在。
      node = node.next;
      arr.push(node);
    }
    arr.map( (x, index) => {
      console.log(`第${index + 1}個節點是:`);
      console.log(x);
    });
}
  • 運行結果:

圖片描述


我的源碼地址app

單鏈表就寫到這裏咯,接下來還會寫其餘的數據結構(本人也在學習當中)。第一次寫文章,有錯漏之處,但願指出。代碼也有能夠精簡的地方,不過這樣我覺讓人看得明白些(大神輕噴)。不過也總算踏出了寫文章的第一步,仍是很開心的。^_^學習

相關文章
相關標籤/搜索