摘要:創(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)建節(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
摘要:實(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)與...
摘要:循環(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)看一...
摘要:鏈表鏈表存儲(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è)好處在于,添加或...
摘要:計(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...
摘要:每個(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)該多掌握一些可移值的...
閱讀 3161·2023-04-25 15:44
閱讀 1902·2019-08-30 13:11
閱讀 2879·2019-08-30 11:11
閱讀 3101·2019-08-29 17:21
閱讀 1334·2019-08-29 15:38
閱讀 987·2019-08-29 12:49
閱讀 1827·2019-08-28 18:19
閱讀 3249·2019-08-26 14:01