日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

[ JavaScript ] 数据结构与算法 —— 链表

發(fā)布時(shí)間:2024/9/21 javascript 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [ JavaScript ] 数据结构与算法 —— 链表 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本篇主要有三部分

  • 什么是鏈表
  • 鏈表的實(shí)現(xiàn)
  • 鏈表的變種

源碼地址:github.com/yhtx1997/Sm…

另外,今天2019年2月18日上午發(fā)現(xiàn) 2048-vue 版,代碼版本不對(duì),且最新版本遺失,無(wú)奈只得重新修復(fù)了下
2048-vue地址: github.com/yhtx1997/Sm…

什么是鏈表

鏈表存儲(chǔ)有序的元素集合,但不同于數(shù)組,鏈表中的元素在內(nèi)存中并不是連續(xù)放置的。每個(gè) 元素由一個(gè)存儲(chǔ)元素本身的節(jié)點(diǎn)和一個(gè)指向下一個(gè)元素的引用(也稱指針或鏈接)組成。
相對(duì)于傳統(tǒng)的數(shù)組,鏈表的一個(gè)好處在于,添加或移除元素的時(shí)候不需要移動(dòng)其他元素。然 而,鏈表需要使用指針,因此實(shí)現(xiàn)鏈表時(shí)需要額外注意。數(shù)組的另一個(gè)細(xì)節(jié)是可以直接訪問(wèn)任何 位置的任何元素,而要想訪問(wèn)鏈表中間的一個(gè)元素,需要從起點(diǎn)(表頭)開(kāi)始迭代列表直到找到 所需的元素。
如下圖:


注:其中 00 06 10 12 18 為假定在內(nèi)存中的地址

我將已經(jīng)做好的鏈表存入數(shù)據(jù),然后在控制臺(tái)打印出來(lái)是這樣的:

它看起來(lái)就像是這樣的,一層套一層

其實(shí)應(yīng)該是下面這樣,類似于栓狗的鐵鏈

鏈表的實(shí)現(xiàn)

鏈表功能

  • 添加元素
  • 獲取指定位置元素
  • 在指定位置插入元素
  • 移除指定位置的元素
  • 返回指定元素的位置
  • 移除指定元素
  • 是否為空
  • 長(zhǎng)度
  • 獲取表頭
  • 清空鏈表
  • 轉(zhuǎn)換為字符串輸出
// 鏈表元素 class Node {constructor(element) {this.element = element; // 元素this.next = undefined; // 指向下一個(gè)元素} } class LinkedList {// 構(gòu)造函數(shù)聲明一些全局變量constructor(){this.count = 0; // 長(zhǎng)度this.head = undefined; // 第一個(gè)元素}// 添加元素push(element) {}// 獲取指定位置元素getElementAt(index) {}// 在指定位置插入元素insert(element, index) {}// 移除指定位置的元素removeAt(index) {}// 返回指定元素的位置indexOf(element) {}// 移除指定元素remove(element) {}// 是否為空isEmpty() {}// 長(zhǎng)度size() {}// 獲取表頭getHead() {}// 清空鏈表clear() {}// 轉(zhuǎn)換為字符串輸出toString() {} } 復(fù)制代碼

代碼實(shí)現(xiàn)

class LinkedList {// 構(gòu)造函數(shù)聲明一些全局變量constructor(){this.count = 0; // 長(zhǎng)度this.head = undefined; // 第一個(gè)元素}// 添加元素push(element) {const node = new Node(element);if (this.head === undefined) {this.head = node;} else {let current = this.head;while (current.next !== undefined) {current = current.next;}current.next = node;}this.count++;}// 獲取指定位置元素getElementAt(index) {// 判斷不是空鏈表if (this.isEmpty() || index > this.count || index < 0) { // 非空才能繼續(xù)處理// 判斷不大于最大長(zhǎng)度,不小于最小長(zhǎng)度(0)return undefined;}// 循環(huán)找到元素let current = this.head;for (let i = 0; i < index; i++){current = current.next;}return current;// 返回找到的元素}// 在指定位置插入元素insert(element, index) {// 創(chuàng)建一個(gè)元素let current = new Node(element);// 首先確定是不是在首位置插入if (index === 0){current.next = this.head;this.head = current;} else {// 找到指定位置前一個(gè)元素let previous = this.getElementAt(index - 1);// 將前一個(gè)元素的 next 賦值給插入元素的 nextcurrent.next = previous.next;// 將插入元素的 node 賦值給前一個(gè)元素的 nextprevious.next = current;}this.count++;}// 移除指定位置的元素removeAt(index) {let current = this.head;if (index === 0){this.head = current.next;} else {// 找到這個(gè)元素和這個(gè)元素之前的元素let previous = this.getElementAt(index - 1);current = previous.next;// 將這個(gè)元素的 next 賦值給這個(gè)元素之前元素的 nextprevious.next = current.next;}this.count--;// 返回要移除的元素return current.element;}// 返回指定元素的位置indexOf(element) {// 從頭開(kāi)始找let current = this.head;// 不超過(guò)最大長(zhǎng)度for (let i = 0; i < this.size() && current != null; i++){if (current.element === element){ // 找到相等的就返回下標(biāo)return i;}current = current.next;}return -1;}// 移除指定元素remove(element) {// 獲取指定元素位置let index = this.indexOf(element);// 移除指定位置元素return this.removeAt(index);}// 是否為空isEmpty() {return this.size() === 0;}// 長(zhǎng)度size() {return this.count;}// 獲取表頭getHead() {return this.head;}// 清空鏈表clear() {this.head = undefined;this.count = 0;}// 轉(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;} } let a = new LinkedList(); a.push('a'); a.push('b'); a.push('c'); a.push('d'); a.push('e'); a.push('f'); a.push('h'); a.push('i'); a.push('j'); a.push('k'); a.push('l'); a.push('m'); a.push('n'); a.push('o'); a.push('p'); a.push('q'); a.remove('a'); a.insert('a',1); console.log(a); 復(fù)制代碼

插入元素圖解:

現(xiàn)在有狗鏈兩節(jié),我要在中間加一節(jié)

先把兩節(jié)分開(kāi),

然后把前邊的尾部與要加的頭部相連,然后把要加的尾部與后邊的頭部相連

0 連 xx , xx 連 1

鏈表的變種

雙向鏈表

我們已經(jīng)知道鏈表的每個(gè)元素由一個(gè)存儲(chǔ)元素本身的節(jié)點(diǎn)和一個(gè)指向下一個(gè)元素的引用(也稱指針或鏈接)組成,雙向鏈表除了這個(gè)基本特性,每個(gè)元素還包含一個(gè)指向前一個(gè)元素的引用,如圖所示:

循環(huán)鏈表

循環(huán)鏈表就是鏈表的最后一個(gè)指向下一個(gè)元素的引用指向了第一個(gè)元素,使其成為循環(huán)鏈表

雙向循環(huán)鏈表

雙向循環(huán)鏈表就是雙向鏈表的第一個(gè)元素指向前一個(gè)的引用指向了最后一個(gè)元素,而最后一個(gè)元素指向下一個(gè)元素的引用指向了第一個(gè)元素,如圖所示:

總結(jié)

以上是生活随笔為你收集整理的[ JavaScript ] 数据结构与算法 —— 链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。