成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript數(shù)據(jù)結(jié)構(gòu)與算法(一)單向鏈表與雙向鏈表

William_Sang / 2214人閱讀

摘要:創(chuàng)建雙向鏈表創(chuàng)建節(jié)點(diǎn)繼承添加前繼指針初始化雙向鏈表對(duì)鏈表最后一個(gè)元素進(jìn)行引用插入操作尾插法任意位置添加元素刪除操作刪除特定位置的元素查詢操作查詢?cè)氐奈恢貌樵兾膊吭匦薷牟僮髑蹇针p向鏈表雙向鏈表對(duì)象轉(zhuǎn)為字符串

線性表 (List):零個(gè)或者多個(gè)數(shù)據(jù)元素的有限序列。線性表是一個(gè)序列,具有一對(duì)一的關(guān)系,而不能具備一對(duì)多的關(guān)系。線性表要求有限性,數(shù)據(jù)類型也要相同。
本文參考的主要是大話數(shù)據(jù)結(jié)構(gòu)的原理進(jìn)行理解,用Javascript實(shí)現(xiàn)線性表的相關(guān)操作。

創(chuàng)建單向鏈表:
//創(chuàng)建節(jié)點(diǎn)
class Node{
    constructor(element){
        this.element = element;//數(shù)據(jù)域
        this.next = undefined;//指針域
    }
};
//判斷傳入的對(duì)象與鏈表的元素是否相等,待會(huì)實(shí)現(xiàn)indexOf()要用到,在這里先寫上
function(a,b){
    return a == b;
}; 
//創(chuàng)建鏈表
class LinkedList {
  constructor(equalsFn = defaultEquals) {
    this.equalsFn = equalsFn;
    this.count = 0;
    this.head = undefined;
    }
};
查詢操作 判斷單向表是否為空
isEmpty() {
    return this.size() === 0;
  }
計(jì)算單向鏈表的長(zhǎng)度
size() {
    return this.count;
  }
查詢鏈表的某個(gè)元素的位置
indexOf(element) {
    let current = this.head;
    for (let i = 0; i < this.size() && current != null; i++) {
      if (this.equalsFn(element, current.element)) {
        return i;
      }
      current = current.next;
    }
    return -1;
  }
獲取第一個(gè)元素
getHead() {
    return this.head;
  }
獲得元素操作
getElementAt(index) {
    if (index >= 0 && index <= this.count) {
      let node = this.head;
      for (let i = 0; i < index && node != null; i++) {
        node = node.next;
      }
      return node;
    }
    return undefined;
  }
插入操作 尾插法
push(element) {
    const node = new Node(element);
    let current;
    if (this.head == null) {
      // catches null && undefined
      this.head = node;
    } else {
      current = this.head;
      while (current.next != null) {
        current = current.next;
      }
      current.next = node;
    }
    this.count++;
  }
任意位置插入元素
insert(element, index) {
    if (index >= 0 && index <= this.count) {
      const node = new Node(element);
      if (index === 0) {
        const current = this.head;
        node.next = current;
        this.head = node;
      } else {
        const previous = this.getElementAt(index - 1);
        node.next = previous.next;
        previous.next = node;
      }
      this.count++;
      return true;
    }
    return false;
  }
刪除操作 刪除特定位置的元素
removeAt(index) {
    if (index >= 0 && index < this.count) {
      let current = this.head;
      if (index === 0) {
        this.head = current.next;
      } else {
        const previous = this.getElementAt(index - 1);
        current = previous.next;
        previous.next = current.next;
      }
      this.count--;
      return current.element;
    }
    return undefined;
  }
直接刪除鏈表的某個(gè)元素
remove(element) {
    const index = this.indexOf(element);
    return this.removeAt(index);
  }
修改操作 單向鏈表轉(zhuǎn)為字符串
toString() {
    if (this.head == null) {
      return "";
    }
    let objString = `${this.head.element}`;
    let current = this.head.next;
    for (let i = 1; i < this.size() && current != null; i++) {
      objString = `${objString},${current.element}`;
      current = current.next;
    }
    return objString;
  }
}
清空單向鏈表
clear() {
    this.head = undefined;
    this.count = 0;
  }

以上就是單向鏈表的常見操作。

由于單向鏈表只能從頭到尾的遍歷,如果查詢得是下一節(jié)點(diǎn),單向表時(shí)間復(fù)雜度為O(1),但是要查詢的是上一節(jié)點(diǎn)的話,那么時(shí)間復(fù)雜度就是O(n)。如果鏈表也可以正反遍歷的話,那么查詢操作的時(shí)間復(fù)雜度就都是O(1)啦,這時(shí)我們的前輩就提出了雙向鏈表這一神奇的鏈表。由于雙向鏈表是單向鏈表的拓展,只是多了一個(gè)指針,對(duì)于查詢操作并沒有幫助,所以實(shí)現(xiàn)方法還是跟單向鏈表一樣,這里就不多加闡述。

創(chuàng)建雙向鏈表
//創(chuàng)建節(jié)點(diǎn)
class DoublyNode extends Node {
  constructor(element, next, prev) {
    super(element, next);//繼承
    this.prev = prev;//添加前繼指針
  }
};
//初始化雙向鏈表
class DoublyLinkedList extends LinkedList {
  constructor(equalsFn = defaultEquals) {
    super(equalsFn);
    this.tail = undefined;//對(duì)鏈表最后一個(gè)元素進(jìn)行引用
  }
插入操作 尾插法
push(element) {
    const node = new DoublyNode(element);
    if (this.head == null) {
      this.head = node;
      this.tail = node; // NEW
    } else {
      // attach to the tail node // NEW
      this.tail.next = node;
      node.prev = this.tail;
      this.tail = node;
    }
    this.count++;
  }
任意位置添加元素
insert(element, index) {
    if (index >= 0 && index <= this.count) {
      const node = new DoublyNode(element);
      let current = this.head;
      if (index === 0) {
        if (this.head == null) { // NEW
          this.head = node;
          this.tail = node; // NEW
        } else {
          node.next = this.head;
          this.head.prev = node; // NEW
          this.head = node;
        }
      } else if (index === this.count) { // last item NEW
        current = this.tail;
        current.next = node;
        node.prev = current;
        this.tail = node;
      } else {
        const previous = this.getElementAt(index - 1);
        current = previous.next;
        node.next = current;
        previous.next = node;
        current.prev = node; // NEW
        node.prev = previous; // NEW
      }
      this.count++;
      return true;
    }
    return false;
  }
刪除操作 刪除特定位置的元素
removeAt(index) {
    if (index >= 0 && index < this.count) {
      let current = this.head;
      if (index === 0) {
        this.head = this.head.next;
        // if there is only one item, then we update tail as well //NEW
        if (this.count === 1) {
          // {2}
          this.tail = undefined;
        } else {
          this.head.prev = undefined;
        }
      } else if (index === this.count - 1) {
        // last item //NEW
        current = this.tail;
        this.tail = current.prev;
        this.tail.next = undefined;
      } else {
        current = this.getElementAt(index);
        const previous = current.prev;
        // link previous with current"s next - skip it to remove
        previous.next = current.next;
        current.next.prev = previous; // NEW
      }
      this.count--;
      return current.element;
    }
    return undefined;
  }
查詢操作 查詢?cè)氐奈恢?/b>
indexOf(element) {
    let current = this.head;
    let index = 0;
    while (current != null) {
      if (this.equalsFn(element, current.element)) {
        return index;
      }
      index++;
      current = current.next;
    }
    return -1;
  }
查詢尾部元素
getTail() {
    return this.tail;
  }
修改操作 清空雙向鏈表
clear() {
    super.clear();
    this.tail = undefined;
  }
雙向鏈表對(duì)象轉(zhuǎn)為字符串
inverseToString() {
    if (this.tail == null) {
      return "";
    }
    let objString = `${this.tail.element}`;
    let previous = this.tail.prev;
    while (previous != null) {
      objString = `${objString},${previous.element}`;
      previous = previous.prev;
    }
    return objString;
  }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106800.html

相關(guān)文章

  • 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)算法(二):鏈表

    摘要:實(shí)現(xiàn)移除給定的元素要移除的元素返回值表示移除成功方法說(shuō)明移除單向鏈表中某個(gè)位置的元素。的前端樂園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法二鏈表 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(三):集合第四篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與...

    lolomaco 評(píng)論0 收藏0
  • Javascript數(shù)據(jù)結(jié)構(gòu)算法(二)循環(huán)鏈表有序鏈表

    摘要:循環(huán)鏈表可以像單向鏈表引用,也可以像雙向鏈表有雙向引用。以下就以如何創(chuàng)建棧數(shù)據(jù)結(jié)構(gòu)為例。 循環(huán)鏈表可以像單向鏈表引用,也可以像雙向鏈表有雙向引用。性能上也跟雙向鏈表差不多,如果position大于length/2,那就可以從尾部開始迭代,可以減少迭代的元素。唯一的區(qū)別在于最后一個(gè)元素指向下一個(gè)元素的指針(tail.next)不是undefine,而是第一個(gè)元素(head)。接下來(lái)來(lái)看一...

    YacaToy 評(píng)論0 收藏0
  • JavaScript數(shù)據(jù)結(jié)構(gòu)算法(四) —— 雙向鏈表

    摘要:鏈表鏈表存儲(chǔ)有序的元素集合,但不同于數(shù)組,鏈表中的元素在內(nèi)存中并不是連續(xù)放置的。鏈表又包括單向鏈表和雙向鏈表雙向鏈表雙向鏈表與單向鏈表很是相像。但在雙向鏈表中,還有指向上一個(gè)節(jié)點(diǎn)的鏈接,是雙向的。 鏈表 鏈表存儲(chǔ)有序的元素集合,但不同于數(shù)組,鏈表中的元素在內(nèi)存中并不是連續(xù)放置的。每個(gè)元素由一個(gè)存儲(chǔ)元素本事的節(jié)點(diǎn)和一個(gè)指向下一個(gè)元素的引用組成。相對(duì)于傳統(tǒng)的數(shù)組,鏈表的一個(gè)好處在于,添加或...

    Youngdze 評(píng)論0 收藏0
  • 【譯】JavaScript數(shù)據(jù)結(jié)構(gòu)(3):單向鏈表雙向鏈表

    摘要:計(jì)算機(jī)科學(xué)中最常見的兩種數(shù)據(jù)結(jié)構(gòu)是單鏈表和雙鏈表。雙向鏈表雙向鏈表具有單鏈表的所有功能,并將其擴(kuò)展為在鏈表中可以進(jìn)行雙向遍歷。雙向鏈表的操作我們的鏈表將包括兩個(gè)構(gòu)造函數(shù)和。與單鏈表不同,雙向鏈表包含對(duì)鏈表開頭和結(jié)尾節(jié)點(diǎn)的引用。 翻譯:瘋狂的技術(shù)宅英文:https://code.tutsplus.com/art...說(shuō)明:本文翻譯自系列文章《Data Structures With Ja...

    Chiclaim 評(píng)論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)算法之美 - 線性表(數(shù)組、棧、隊(duì)列、鏈表

    摘要:每個(gè)線性表上的數(shù)據(jù)最多只有前和后兩個(gè)方向。數(shù)組鏈表隊(duì)列棧等就是線性表結(jié)構(gòu)。非線性表數(shù)據(jù)之間并不是簡(jiǎn)單的前后關(guān)系。不包含任何元素的棧稱為空棧。移除棧頂?shù)脑兀瑫r(shí)返回被移除的元素。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 前言 基礎(chǔ)知識(shí)就像是一座大樓的地基,它決定了我們的技術(shù)高度。 我們應(yīng)該多掌握一些可移值的...

    kaka 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<