天天看點

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

資料結構之“連結清單”

  • 連結清單是什麼?
  • 數組 vs 連結清單
  • JS中的連結清單
  • LeetCode:237.删除連結清單中的節點
  • LeetCode:206.反轉連結清單
  • LeetCode:2.兩數相加
  • LeetCode:83.删除排序連結清單中的重複元素
  • LeetCode:141.環形連結清單
  • 前端與連結清單(JS中的原型鍊)
    • 一、instanceof的使用,并用代碼實作
  • 前端連結清單:使用連結清單指針擷取JSON的節點值
  • 總結
  • 思考題

連結清單是什麼?

多個元素組成的清單

元素存儲不連續,用next指針連在一起

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

數組 vs 連結清單

數組:增删非首尾元素是往往需要移動元素

連結清單:增删非首尾元素,不需要移動元素,隻需要更改next的指向即可

JS中的連結清單

JavaScript中沒有連結清單

可以用Object模拟連結清單

const a = { val: 'a' };
const b = { val: 'b' };
const c = { val: 'c' };
const d = { val: 'd' };
a.next = b;
b.next = c;
c.next = d;

// 周遊連結清單
let p = a;
while (p) {
    console.log(p.val);
    p = p.next;
}

// 插入
const e = { val: 'e' };
c.next = e;
e.next = d;

// 删除
c.next = d;

           

LeetCode:237.删除連結清單中的節點

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

解題思路

無法直接擷取被删除節點的上個節點

将被删除節點轉移到下個節點

解題步驟

将被删節點的值改為下個節點的值

删除下個節點

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

時間複雜度O(1),空間複雜度O(1)

LeetCode:206.反轉連結清單

輸入: 1->2->3->4->5->NULL

輸出: 5->4->3->2->1->NULL

解題思路

反轉兩個節點:将n + 1的next指向n

反轉多個節點:雙指針周遊連結清單,重複上述操作

解題步驟

雙指針一前一後周遊連結清單

反轉雙指針

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

時間複雜度O(n),空間複雜度O(1)

LeetCode:2.兩數相加

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

輸出:7 -> 0 -> 8

原因:342 + 465 = 807

解題思路

國小數學題,模拟相加操作

需要周遊連結清單

解題步驟

建立一個空連結清單

周遊被相加的兩個連結清單,模拟相加操作,将個位數追加到新連結清單上,将十位數留到下一位去相加

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

時間複雜度O(n),空間複雜度O(n)

LeetCode:83.删除排序連結清單中的重複元素

輸入:1 -> 1 -> 2

輸出:1 -> 2

解題思路

因為連結清單是有序的,是以重複元素一定相鄰

周遊連結清單,如果發現目前元素和下個元素值相同,就删除下個元素值

解題步驟

周遊連結清單,如果發現目前元素和下個元素值相同,就删除下個元素值

周遊結束後,傳回原連結清單的頭部

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

時間複雜度O(n),空間複雜度O(1)

LeetCode:141.環形連結清單

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

解題思路

兩個人在圓形操場上的起點同時起跑,速度快的人一定會超過速度慢的人一圈

用一快一慢兩個指針周遊連結清單,如果指針能夠相逢,那麼連結清單就有圈

解題步驟

用一快一慢兩個指針周遊連結清單,如果指針能夠相逢,就傳回true

周遊結束後,還沒有相逢就傳回false

(五)資料結構之“連結清單”連結清單是什麼?數組 vs 連結清單JS中的連結清單LeetCode:237.删除連結清單中的節點LeetCode:206.反轉連結清單LeetCode:2.兩數相加LeetCode:83.删除排序連結清單中的重複元素LeetCode:141.環形連結清單前端與連結清單(JS中的原型鍊)二前端連結清單:使用連結清單指針擷取JSON的節點值總結思考題

時間複雜度O(n),空間複雜度O(1)

前端與連結清單(JS中的原型鍊)

原型鍊簡介

原型鍊的本質是連結清單

原型鍊上的節點是各種原型對象,比如Function.prototype、Object.prototype…

原型鍊通過__proto__屬性連結各種原型對象

原型鍊長啥樣

obj -> Object.prototype -> null

func -> Function.prototype -> Object.prototype -> null

arr -> Array.prototype -> Object.prototype -> null

原型鍊知識點

如果A沿着原型鍊能找到B的原型對象(B.prototype),那麼A instanceof B為true

如果在A對象上沒有找到x屬性,那麼會沿着原型鍊找x屬性

const obj = {}
const func = () => {}
const arr = []
//原型鍊通過__proto__屬性連結各種原型對象
console.log(obj .__proto__ === Object.prototype) //true
console.log(func.__proto__ === Function.prototype) //true
console.log(func.__proto__.__proto__ === Object.prototype) //true
console.log(arr.__proto__ === Array.prototype) //true
console.log(arr.__proto__.__proto__ === Object.prototype) //true

//如果A沿着原型鍊能找到B的原型對象(B.prototype),那麼A instanceof B為true
console.log(func instanceof Function) //true
console.log(func instanceof Object) //true
//fuc的proto屬性指向Function的原型對象,
//func即是object的執行個體,也是function的執行個體

//如果在A對象上沒有找到x屬性,那麼會沿着原型鍊找x屬性
const obj = {};
Object.prototype.x = 'x'
const func = () => {};
Function.prototype.y = 'y'
console.log(obj.x) //x
console.log(obj.y) //undefined
console.log(func.x) //x
console.log(func.y) //y
           

一、instanceof的使用,并用代碼實作

分析

知識點:如果A沿着原型鍊能找到B.prototype,那麼A instanceof B為true

解法:周遊A的原型鍊,如果找到B.prototype,傳回true,否則傳回false

const instanceOf = (A,B) => {
	let p = A;
	while (p) {
		if (p === B.prototype) {
			return true;
		}
		p = p.__proto__;
	}
	return false;
}
 
           

var foo = {},F = Function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b'

console.log(foo.a)
console.log(foo.b)

console.log(F.a)
console.log(F.b)
 
           

分析

知識點:如果在A對象上沒有找到x屬性,那麼會沿着原型鍊找x屬性

解法:明确foo和F變量的原型鍊,沿着原型鍊找a屬性和b屬性

前端連結清單:使用連結清單指針擷取JSON的節點值

const json = {
	a: { b: { c: 1 } },
	d: { e: 2 },  
}
const path = ['a', 'b' ,'c']
let p =json;
path.forEach(k => {
	p = p[k];
})
 
           

總結

連結清單裡的元素存儲不是連續的,之間通過next連接配接

JavaScript中沒有連結清單,但可以用Object模拟連結清單

連結清單常用操作:修改next、周遊連結清單

JS中的原型鍊也是一個連結清單

使用連結清單指針可以擷取JSON的節點值

思考題

1、編寫一個 instanceOf 方法,可以判斷一個變量是否是另一個變量的執行個體

2、請判斷一個連結清單是否為回文連結清單。題目連結:https://leetcode-cn.com/problems/palindrome-linked-list/