摘要:我對鏈表的學習什么是鏈表要存儲多個元素,數組可能是最常用的數據結構。鏈表的學習創建一個鏈表各種方法表示要加入列表的項,它包含一個屬性以及一個屬性,表示要添加到列表的值,表示指向列表下一個節點項的指針。
我對JS鏈表的學習 什么是鏈表
要存儲多個元素,數組可能是最常用的數據結構。這種數據結構非常方便,但是有一個缺點:從數組的起點或者中間插入或移除項的成本非常高,因為需要移動元素(比如你插入一個元素后面的所有的元素都移動了“位置”)。
鏈表存儲有序的元素集合,但是不同于數組,鏈表中的元素在內存中并不是連續放置的。每個元素都是由一個存儲元素本身的節點和一個指向下一元素的引用(也叫指針或者鏈接)組成。
相比于數組來說,鏈表的好處在于添加或者刪除元素的時候不需要移動其他元素。但是操作鏈表需要使用指針。數組的一個優點是可以直接訪問任何位置的任何元素,但是要是想訪問鏈表中的某一元素,則是必須從起點開始迭代直到找到目標元素。
鏈表的學習創建一個鏈表
function LinkedList() { var Node = function(element) { this.element = element; this.next = null; } //各種方法 }
Node表示要加入列表的項,它包含一個element屬性以及一個next屬性,element表示要添加到列表的值,next表示指向列表下一個節點項的指針。
當一個Node元素被創建時,它的next指針總是null
向鏈表尾部追加元素
列表為空,添加的是第一個元素。列表不為空,向其追加元素。
要循環訪問列表中的所有元素,就需要有一個起點,就是head
this.append = function(element) { var node = new Node(element), //傳入值創建Node項 current; if(head === null) { //如果為空鏈表 head = node; //設置node為head(head為第一個節點的引用) } else { current = head; //從表頭開始 while(current.next) { //循環列表,找到最后一項(列表最后一個節點的下一個元素始終是null) current = current.next; } //使當前最后一項的指針指向node current.next = node; } length++; //更新列表長度 };
使用append
var list = new LinkedList(); list.append(15); list.append(10);
從鏈表移除元素
輸入位置,從特定位置移除一個元素
this.removeAt = function(position) { if(position > -1 && position < length) { //有效性檢測 var current = head, //用current來循環列表 previous, index = 0; if(position === 0) { head = current.next; //移除第一個元素,直接把head指向下一個元素 } else { while(index++ < position) { //循環列表找到滿足條件的那個元素 previous = current; // current = current.next; //把下一個變量覆給current } //跳過current,將當前要移除的元素的上一個與下一項直接連接起來。 previous.next = current.next; } length --; return current.element; } else { return null; } }
在任意位置插入一個元素
this.insert = function (position, element) { if(position >= 0 && position <= length) { var node = new Node(element), current = head; //通過current從head位置開始迭代 previous, index = 0; if(position === 0) { //第一個位置 node.next = current; //此時current = head,指向head那么node就成了第一個 head = node; //node指向為head } else { while (index++ < position ) { //循環迭代到目標位置 previous = current; current = current.next; } node.next = current; // node的下一個為current previous.next = node; // node的上一個位置為previous } length++; return true; } else { return false; } }
把LinkedList對象轉換成一個字符串。
this.toString = function() { var current = head, string = ""; while(current) { //循環訪問列表 string += current.element + (current.next ? " " : ""); current = current.next; } return string; //返回字符串 }
返回元素的位置
this.indexOf = function(element) { var current = head, index = 0; while(current) { if(element === current.element) { return index; //找到返回當前位置 } index ++; current = current.next; } return -1; //找不到返回-1 }
輸入元素,移除該元素
this.remove = function(element) { var index = this.indexOf(element); //得到元素的位置 return this.removeAt(index); //移除該元素 }
判斷是否為空 得到長度 得到第一個元素
this.isEmpty = function () { return length === 0; } this.size = function () { return length; } this.getHead = function () { return head; }雙向鏈表
他和普通鏈表的區別,在雙向鏈表中,鏈接是雙向的,一個鏈向下一個元素一個鏈向上一個元素。在操作雙向鏈表的時候既要像普通鏈表一樣考慮next,也要考慮prev。
雙向列表提供了兩種迭代列表的方法:從頭到尾迭代,或者反過來。
創建一個雙向列表
function DoublyLinkedList() { var Node = function(element) { this.element = element; this.next = null; this.prev = null; //新指針 }; var length = 0; var head = null; var tail = null; //對列表最后一項的引用 //各種方法 }
在任意位置插入一個新元素
this.insert = function(position, element) { if(position >= 0 && position <= length) { var node = new Node(element), current = head, previous, index = 0; if(position === 0) { //在第一個位置添加 if(!head) { //如果head不存在即鏈表為空 head = node; tail = node; } else { //鏈表不為空 node.next = current; current.prev = node; head = node; } } else if(position === length) { //在最后一個位置添加 current = tail; current.next = node; node.prev = current; tail = node; } else { while(index++ < position) { //在列表中間添加 previous = current; //循環迭代 current = current.next; } node.next = current; previous.next = node; current.prev = node; node.prev = previous; } length ++; //更新列表長度 return true; } else { return false; } }
從任意位置移除元素
this.removeAt = function(position) { if(position > -1 && position < length) { //檢查越界值 var current = head, previous, index = 0; if(position === 0) { //第一個位置 head = current.next; if(length === 1) { //如果鏈表只有一項 tail = null; } else { //也就相當于把current.next.prev = null head.prev = null; } } else if(position === length -1) { //最后一項 current = tail; //tail的引用賦給current變量 tail = current.prev; //上一項指向tail tail.next = null; //最后一項的next都是指向null的 } else { while(index++ < position) { //從中間位置移除 previous = current; current = current.next; } previous.next = current.next; //直接跳過current連接上一項和下一項 current.next.prev = previous; } length --; return current.element; } else { return null; } }循環鏈表
單向循環鏈表和鏈表唯一去別在于:最后一個元素指向下一個元素的指針(tail.next)不是引用null而是指向第一個元素(head)
雙向循環鏈表有指向head的tail.next,也有指向tail的head.prev
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82004.html
摘要:對散列表的簡單學習類也叫類,是類的一種散列表實現方式。鍵值散列函數散列值形成散列表地址數據鍵值對相關操作方法創建一個散列表實現一個散列函數,即將碼值相加的方法。 對JS散列表的簡單學習 HashTable類也叫HashMap類,是Dictionary類的一種散列表實現方式。 散列算法的作用是盡可能快的在數據結構中找到一個值。 在之前的學習中,如果你想要獲得數據結構中的一個值,需要遍歷整...
摘要:既然說到地址空間了就順帶說一下上面環形鏈表這道題的另一種很的解法吧。介紹完常規操作鏈表的一些基本知識點后,現在回到快慢指針。 ??前幾天第一次在 Segmentfault 發文—JavaScript:十大排序的算法思路和代碼實現,發現大家似乎挺喜歡算法的,所以今天再分享一篇前兩個星期寫的 Leetcode 刷題總結,希望對大家能有所幫助。 ??本文首發于我的blog 前言 ??今天終于...
摘要:上一篇數據結構與算法棧隊列下一篇數據結構與算法集合字典寫在前面說明數據結構與算法系列文章的代碼和示例均可在此找到上一篇博客發布以后,僅幾天的時間竟然成為了我寫博客以來點贊數最多的一篇博客。 上一篇:JS數據結構與算法_棧&隊列下一篇:JS數據結構與算法_集合&字典 寫在前面 說明:JS數據結構與算法 系列文章的代碼和示例均可在此找到 上一篇博客發布以后,僅幾天的時間竟然成為了我寫博客以...
摘要:在存儲多個元素時,我們最常用的數據結構可能是數組,究其原因可能是數組訪問方便,可以直接通過訪問,但是數組也存在一定的缺點,數組的大小是固定,數組在執行插入或者刪除的時候成本很高。 在存儲多個元素時,我們最常用的數據結構可能是數組,究其原因可能是數組訪問方便,可以直接通過[]訪問,但是數組也存在一定的缺點,數組的大小是固定,數組在執行插入或者刪除的時候成本很高。鏈表存儲的是有序的元素集合...
閱讀 1839·2021-09-14 18:03
閱讀 2274·2019-08-30 15:48
閱讀 1129·2019-08-30 14:09
閱讀 515·2019-08-30 12:55
閱讀 2735·2019-08-29 11:29
閱讀 1494·2019-08-26 13:43
閱讀 2318·2019-08-26 13:30
閱讀 2376·2019-08-26 12:17