成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

美女面試官問我鏈表的CURD,我徹底懵圈了……

開發 前端
鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。

一、基礎

1、定義

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。

2、相關概念

一個完整的鏈表需要由以下幾個部分組成:

  1. 頭指針:一個普通的指針,它的特點是永遠指向鏈表第一個結點的位置。
  2. 結點:節點包含三類:頭結點、首元節點和其它節點。

(1)頭結點(非必須):一個不存任何數據的空節點,通常作為鏈表的第一個節點。

(2)首元結點:鏈表中第一個存有數據的節點稱為首元結點。

(3)其它結點:鏈表中的其它結點。

3、結點包含內容

鏈表中每個節點包含兩個部分:

  1. 數據域:存儲數據元素本身。
  2. 指針域:指向直接后續元素的指針。

二、鏈表分類及相關操作

鏈表存在很多種類,下面重點講述單向鏈表、雙向鏈表的結點結構,以及其對應的CURD(添加、更改、查找、刪除)。

1、 單向鏈表

對于單鏈表的相應編程,我們均按照默認頭指針指向首元結點這樣的結構進行代碼實現。

(1)結點結構

結點作為鏈表的重要組成部分,其結構可用如下代碼表示:

function ListNode(val, next) {
this.val = val;
this.next = next === undefined ? null : next;
}

擴展:如何根據一個數組創建鏈表。

function createLinkedList(arr) {
const head = new ListNode(arr[0]);
let current = head;
for (let i = 1; i < arr.length; i++) {
const node = new ListNode(arr[i]);
current.next = node;
current = current.next;
}
return head;
}

(2)遍歷(查找)

在鏈表中查找指定數據元素,其思路是從表頭依次遍歷表中節點,用被查找元素與各結點中存儲的數據元素進行對比,直到對比成功或遍歷至鏈表最末端的null。

// 查找
function selectVal(head, val) {
let current = head;
// 判斷是否為null
while (current) {
// 判斷是否對比成功
if (current.val === val) {
return current;
}
current = current.next;
}
return null;
}

(3)添加

向鏈表中添加元素,根據添加位置不同,可分為3中情況:

  1. 插入到鏈表的頭部。
  2. 插入到鏈表中間的某個位置。
  3. 插入到鏈表的最末端,作為鏈表中最后一個數據元素。

插入思想

  1. 將新結點的next指針指向插入位置后的結點。
  2. 將插入位置前結點的next指針指向插入結點。
function insertVal(head, val, add) {
const newNode = new ListNode(add);
// 查找插入節點
const currentNode = selectVal(head, val);
if (!currentNode) {
return null;
}
// 1. 將新結點的next指針指向插入位置后的節點
newNode.next = currentNode.next;
// 2. 將插入位置前節點的next指針指向插入節點
currentNode.next = newNode;
return head;
}

(4)刪除

刪除的元素的時候要注意鏈表的結構,注意有沒有空值的頭結點,有頭結點的時候刪除的時候就不需要判斷刪除的是不是第一個值,否則需要進行判斷。

function delVal(head, val) {
// 當一個結點也不存在時,直接返回空
if (!head) {
return null;
}
// 如果刪除的是第一個節點,直接將head指向第二個節點
if (head.val === val) {
head = head.next;
return head;
}
// 如果刪除的不是第一個節點
let current = head;
// 找到待刪除元素的前一個值
while (current.next && current.next.val !== val) {
current = current.next;
}
if (current.next) {
// 將刪除結點的前一個結點的next值直接指向刪除結點的下一個節點
current.next = current.next.next;
}
return head;
}

(5)更改

更新鏈表中的元素,只需要通過遍歷找到存儲此元素的節點,對節點中的數據域做更改操作即可。

function updateVal(head, val, newVal) {
let current = head;
while (current) {
if (current.val === val) {
current.val = newVal;
return head;
}
current = current.next;
}
return null;
}

2、 雙向鏈表

單鏈表只有一個方向,從頭結點到尾結點,雙向鏈表指各個節點之間的邏輯關系是雙向的,其結點結構和鏈表結構如下所示:

結點結構:

鏈表結構:

(1)結點結構

雙向鏈表的節點結構相比于單向鏈表,多了一個prev屬性,如下所示:

function ListNode(val, prev, next) {
this.val = val;
this.prev = prev === undefined ? null : prev;
this.next = next === undefined ? null : next;
}

(2)遍歷(查找)

雙向鏈表的查找和單向鏈表的查找類似,都是遍歷鏈表。

function selectVal(head, val) {
let current = head;
while (current) {
if (current.val === val) {
return current;
}
current = current.next;
}
return null;
}

(3)添加

在某個節點后插入結點,其思想是:

  1. 找到該插入結點。
  2. 將新結點的next指針指向插入位置后的結點。
  3. 將新結點的prev指針指向插入位置的結點。
  4. 將插入節點的next指針指向新結點。
/**
* 插入(在某個節點后插入)
*/
function insertVal(head, val, add) {
const newNode = new ListNode(add);
// 查找插入節點
const currentNode = selectVal(head, val);
if (!currentNode) {
return null;
}
// 1. 將新結點的next指針指向插入位置后的結點
newNode.next = currentNode.next;
// 2. 將新結點的prev指針指向插入位置的結點
newNode.prev = currentNode;
// 3. 將插入節點的next指針指向新結點
currentNode.next = newNode;
return head;
}

(4)刪除

雙鏈表刪除結點時,只需要遍歷鏈表找到要刪除的鏈表,然后將該鏈表從表中摘除即可。

(注:針對頭指針直線的結點需要做特殊處理,否則head永遠指向的是原始的第一個節點)。

/**
* 刪除
*
* 雙鏈表刪除結點時,只需要遍歷鏈表找到要刪除的鏈表,然后將該鏈表從表中摘除即可
*/
function delVal(head, val) {
let current = head;
while (current) {
if (current.val === val) {
if (current.next) {
current.next.prev = current.prev;
}
if (current.prev) {
current.prev.next = current.next;
} else {
// 針對頭指針直線的結點需要做特殊處理,否則head永遠指向的是原始的第一個節點
head = current.next;
}
return head;
}
current = current.next;
}
return null;
}

(5)更改

更新鏈表中的元素,只需要通過遍歷找到存儲此元素的節點,對節點中的數據域做更改操作即可。

/**
* 更新
*
* 更新鏈表中的元素,只需要通過遍歷找到存儲此元素的節點,對節點中的數據域做更改操作即可
*/
function updateVal(head, val, newVal) {
let current = head;
while (current) {
if (current.val === val) {
current.val = newVal;
return head;
}
current = current.next;
}
return null;
}
責任編輯:姜華 來源: 前端點線面
相關推薦

2021-12-02 08:19:06

MVCC面試數據庫

2023-01-26 02:16:17

2020-06-22 08:50:27

Spring AOP代理

2022-10-17 00:04:30

索引SQL訂單

2020-04-16 08:22:11

HTTPS加解密協議

2022-10-12 14:39:27

Streammappeek

2019-08-28 14:25:00

線程安全容器

2020-12-01 11:50:49

數據庫Redis面試

2021-11-24 10:10:32

axios前端攔截器

2020-12-03 07:39:50

HashMap底層數據

2022-05-24 08:03:28

InnoDBMySQL數據

2021-05-08 07:53:33

面試線程池系統

2021-10-25 08:49:32

索引數據庫MySQL

2021-04-01 08:12:20

zookeeper集群源碼

2021-12-06 08:30:49

SpringSpring Bean面試題

2021-11-02 09:05:25

Redis

2021-05-20 08:54:16

Go面向對象

2010-08-23 15:06:52

發問

2021-11-12 06:39:51

Tomcat連接器面試

2020-11-12 18:20:28

接口數據分布式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久国产精品 | 瑞克和莫蒂第五季在线观看 | 精品国产一区二区三区性色av | 欧美一级久久 | 成人综合一区 | 精品久久精品 | 久久国产精品一区二区三区 | 免费观看av | 亚洲国产成人精品女人久久久野战 | 午夜激情小视频 | 日韩毛片在线视频 | 国产乱码精品一品二品 | 久久丝袜视频 | 9porny九色视频自拍 | 国精产品一区一区三区免费完 | 国产一区二区三区四区在线观看 | www.中文字幕.com | 一本色道精品久久一区二区三区 | 中文字幕日韩欧美一区二区三区 | 夜夜干夜夜操 | 久久爱黑人激情av摘花 | 天堂在线免费视频 | 日韩午夜| 涩涩视频在线观看 | 97国产精品视频人人做人人爱 | 黄色日批视频 | 成人免费在线小视频 | 久久精品久久久 | 日本电影免费完整观看 | 亚洲视频一区 | 99精品欧美一区二区三区 | 黄色网址av| 国产999精品久久久久久 | 精品国产乱码一区二区三区 | 国产美女自拍视频 | 在线三级网址 | 精品国产乱码久久久久久蜜柚 | 美国av毛片 | 91成人免费 | 一区二区三区国产 | 亚洲欧美一区二区三区视频 |