能更好地理解數(shù)據(jù)結(jié)構(gòu)的工作方式
聽起來熟悉嗎?“我結(jié)束了在線課程,開始開發(fā)前端?!?
可以為計算機科學(xué)特別是數(shù)據(jù)結(jié)構(gòu)和算法的改進尋求基礎(chǔ)。今天將介紹一些常見的數(shù)據(jù)結(jié)構(gòu),并使用JavaScript實現(xiàn)。
希望這部分能補充大家的技術(shù)!
1.堆疊堆棧
堆棧遵循LIFO(后進先出)的原理。堆積書的話,最上面的書會在最下面的書前面?;蛘?,在瀏覽互聯(lián)網(wǎng)時,按“后退”按鈕可轉(zhuǎn)至最近訪問的頁面。
Stack有以下常用方法:
推式:輸入新元素
Pop:刪除頂部元素并返回刪除的元素
Peek:返回頂部元素
長度:返回堆棧中元素的數(shù)量
Javascript中的數(shù)組具有Stack的屬性,但使用Stack()函數(shù)從頭開始構(gòu)建Stack
Function Stack() {
=0;
={ };
=function(值){
[]=值;
中選擇另一種天花板類型。
}
=function () {
If (===0) {
Return undefined
}
-;
var result=[];
刪除[];
Return result
}
=function () {
return[-1];
}
=function () {
Return
}
}2 .隊列隊列
隊列類似于堆棧。唯一的區(qū)別是Queue使用FIFO原理(先進先出)。也就是說,在等公交車的時候,隊列中的第一個總是第一個。
隊列有以下方法:
排入佇列:輸入佇列并將元素新增至結(jié)尾
出隊:結(jié)束隊列,移去舊元素,然后返回
Front:匯入第一個零件
Isempty:確定隊列是否為空
大小:獲取隊列中的元素數(shù))
JavaScript中的數(shù)組具有Queue的某些屬性,因此可以使用數(shù)組構(gòu)造Queue的示例。
Function Queue() {
var collection=[];
=function () {
集合(con);
}
=function(元素){
COLLEC(ELEMEMENT);
}
=function () {
return collec();
}
=function () {
return collection[0];
}
=function () {
Return collec====
}
=function () {
Return collec
}
}優(yōu)先級隊列
隊列有另一個高級版本。為每個元素指定優(yōu)先級,并按優(yōu)先級排序。
Function PriorityQueue() {
.
=function(元素){
if(){
COLLEC(ELEMEMENT);
} else
Var added=false
for(var I=0;I collecI) {
If (element [1]集合[I] [1]) {
Collec(i,0,element);
Added=true
布雷克;
}
}
If(!Added) {
COLLEC(ELEMEMENT);
}
}
}
}測試:
var pQ=new priority queue();
([gannicus,3]);
([Spartacus,1]);
([crixus,2]);
([奧諾瑪默斯,4]);
();結(jié)果:
[
[Spartacus,1],
[crix
us , 2 ], [ gannicus , 3 ], [ oenomaus , 4 ] ]3.鏈表
從字面上看,鏈表是一個鏈式數(shù)據(jù)結(jié)構(gòu),每個節(jié)點由兩部分信息組成:該節(jié)點的數(shù)據(jù)和指向下一個節(jié)點的指針。 鏈表和常規(guī)數(shù)組都是帶有序列化存儲的線性數(shù)據(jù)結(jié)構(gòu)。 當然,它們也有差異:
單邊鏈表通常具有以下方法:
· size:返回節(jié)點數(shù)
· head:返回head的元素
· add:在尾部添加另一個節(jié)點
· delete:刪除某些節(jié)點
· indexOf:返回節(jié)點的索引
· elementAt:返回索引的節(jié)點
· addAt:在特定索引處插入節(jié)點
· removeAt:刪除特定索引處的節(jié)點
/** Node in the linked list **/ function Node(element) { // Data in the node = element; // Pointer to the next node = null; } function LinkedList() { var length = 0; var head = null; = function () { return length; } = function () { return head; } = function (element) { var node = new Node(element); if (head == null) { head = node; } else { var currentNode = head; while ) { currentNode = curren; } curren = node; } length++; } = function (element) { var currentNode = head; var previousNode; if === element) { head = curren; } else { while !== element) { previousNode = currentNode; currentNode = curren; } = curren; } length--; } = function () { return length === 0; } = function (element) { var currentNode = head; var index = -1; while (currentNode) { index++; if === element) { return index; } currentNode = curren; } return -1; } At = function (index) { var currentNode = head; var count = 0; while (count < index) { count++; currentNode = curren; } return curren; } At = function (index, element) { var node = new Node(element); var currentNode = head; var previousNode; var currentIndex = 0; if (index > length) { return false; } if (index === 0) { node.next = currentNode; head = node; } else { while (currentIndex < index) { currentIndex++; previousNode = currentNode; currentNode = curren; } node.next = currentNode; = node; } length++; } At = function (index) { var currentNode = head; var previousNode; var currentIndex = 0; if (index < 0 || index >= length) { return null; } if (index === 0) { head = curren; } else { while (currentIndex < index) { currentIndex++; previousNode = currentNode; currentNode = curren; } = curren; } length--; return curren; } }4.集合
集合是數(shù)學(xué)的基本概念:定義明確且不同的對象的集合。 ES6引入了集合的概念,它與數(shù)組有一定程度的相似性。 但是,集合不允許重復(fù)元素,也不會被索引。
一個典型的集合具有以下方法:
· values:返回集合中的所有元素
· size:返回元素數(shù)
· has:確定元素是否存在
· add:將元素插入集合
· delete:從集合中刪除元素
· union:返回兩組的交集
· difference:返回兩組的差異
· subset:確定某個集合是否是另一個集合的子集
為了區(qū)分ES6中的集合,在以下示例中我們聲明為MySet:
function MySet() { var collection = []; = function (element) { return (element) !== -1); } = function () { return collection; } = function () { return collec; } = function (element) { if (!(element)) { collec(element); return true; } return false; } = function (element) { if ((element)) { index = collec(element); collec(index, 1); return true; } return false; } = function (otherSet) { var unionSet = new MySet(); var firstSet = (); var secondSet = o(); (function (e) { unionSet.add(e); }); (function (e) { unionSet.add(e); }); return unionSet; } = function (otherSet) { var intersectionSet = new MySet(); var firstSet = (); (function (e) { if (e)) { in(e); } }); return intersectionSet; } = function (otherSet) { var differenceSet = new MySet(); var firstSet = (); (function (e) { if (!o(e)) { di(e); } }); return differenceSet; } = function (otherSet) { var firstSet = (); return (function (value) { return o(value); }); } }5.哈希表
哈希表是鍵值數(shù)據(jù)結(jié)構(gòu)。 由于通過鍵查詢值的閃電般的速度,它通常用于Map,Dictionary或Object數(shù)據(jù)結(jié)構(gòu)中。 如上圖所示,哈希表使用哈希函數(shù)將鍵轉(zhuǎn)換為數(shù)字列表,這些數(shù)字用作相應(yīng)鍵的值。 要快速使用鍵獲取價值,時間復(fù)雜度可以達到O(1)。 相同的鍵必須返回相同的值-這是哈希函數(shù)的基礎(chǔ)。
哈希表具有以下方法:
· add:添加鍵值對
· delete:刪除鍵值對
· find:使用鍵查找對應(yīng)的值
Java簡化哈希表的示例:
function hash(string, max) { var hash = 0; for (var i = 0; i < ; i++) { hash += (i); } return hash % max; } function HashTable() { let storage = []; const storageLimit = 4; = function (key, value) { var index = hash(key, storageLimit); if (storage[index] === undefined) { storage[index] = [ [key, value] ]; } else { var inserted = false; for (var i = 0; i < storage[index].length; i++) { if (storage[index][i][0] === key) { storage[index][i][1] = value; inserted = true; } } if (inserted === false) { storage[index].push([key, value]); } } } = function (key) { var index = hash(key, storageLimit); if (storage[index].length === 1 && storage[index][0][0] === key) { delete storage[index]; } else { for (var i = 0; i < storage[index]; i++) { if (storage[index][i][0] === key) { delete storage[index][i]; } } } } = function (key) { var index = hash(key, storageLimit); if (storage[index] === undefined) { return undefined; } else { for (var i = 0; i < storage[index].length; i++) { if (storage[index][i][0] === key) { return storage[index][i][1]; } } } } }6.樹
樹數(shù)據(jù)結(jié)構(gòu)是多層結(jié)構(gòu)。 與Array,Stack和Queue相比,它也是一種非線性數(shù)據(jù)結(jié)構(gòu)。 在插入和搜索操作期間,此結(jié)構(gòu)非常高效。 讓我們看一下樹數(shù)據(jù)結(jié)構(gòu)的一些概念:
· root:樹的根節(jié)點,無父節(jié)點
· parent 父節(jié)點:上層的直接節(jié)點,只有一個
· children 子節(jié)點:較低層的直接節(jié)點,可以有多個
· siblings 兄弟姐妹:共享同一父節(jié)點
· leaf 葉:沒有子節(jié)點
· edge 邊緣:節(jié)點之間的分支或鏈接
· path 路徑:從起始節(jié)點到目標節(jié)點的邊緣
· height of node 節(jié)點高度:特定節(jié)點到葉節(jié)點的最長路徑的邊數(shù)
· height of tree 樹的高度:根節(jié)點到葉節(jié)點的最長路徑的邊數(shù)
· depth of node 節(jié)點深度:從根節(jié)點到特定節(jié)點的邊數(shù)
· degree of node 節(jié)點度:子節(jié)點數(shù)
這是二叉搜索樹的示例。 每個節(jié)點最多有兩個節(jié)點,左節(jié)點小于當前節(jié)點,右節(jié)點大于當前節(jié)點:
二進制搜索樹中的常用方法:
· add:在樹中插入一個節(jié)點
· findMin:獲取最小節(jié)點
· findMax:獲取最大節(jié)點
· find:搜索特定節(jié)點
· isPresent:確定某個節(jié)點的存在
· delete:從樹中刪除節(jié)點
JavaScript中的示例:
class Node { constructor(data, left = null, right = null) { = data; = left; = right; } } class BST { constructor() { = null; } add(data) { const node = ; if (node === null) { = new Node(data); return; } else { const searchTree = function (node) { if (data < node.data) { if === null) { node.left = new Node(data); return; } else if !== null) { return searchTree); } } else if (data > node.data) { if === null) { node.right = new Node(data); return; } else if !== null) { return searchTree); } } else { return null; } }; return searchTree(node); } } findMin() { let current = ; while !== null) { current = current.left; } return current.data; } findMax() { let current = ; while !== null) { current = current.right; } return current.data; } find(data) { let current = ; while !== data) { if (data < current.data) { current = current.left } else { current = current.right; } if (current === null) { return null; } } return current; } isPresent(data) { let current = ; while (current) { if (data === current.data) { return true; } if (data < current.data) { current = current.left; } else { current = current.right; } } return false; } remove(data) { const removeNode = function (node, data) { if (node == null) { return null; } if (data == node.data) { // no child node if == null && node.right == null) { return null; } // no left node if == null) { return node.right; } // no right node if == null) { return node.left; } // has 2 child nodes var tempNode = node.right; while !== null) { tempNode = ; } node.data = ; node.right = removeNode, ); return node; } else if (data < node.data) { node.left = removeNode, data); return node; } else { node.right = removeNode, data); return node; } } = removeNode(, data); } }測試一下:
const bst = new BST(); b(4); b(2); b(6); b(1); b(3); b(5); b(7); b(4); con()); con()); b(7); con()); con(4));結(jié)果:
1 7 6 false7.Trie(發(fā)音為" try")
Trie或"前綴樹"也是一種搜索樹。 Trie分步存儲數(shù)據(jù)-樹中的每個節(jié)點代表一個步驟。 Trie用于存儲詞匯,因此可以快速搜索,尤其是自動完成功能。
Trie中的每個節(jié)點都有一個字母-在分支之后可以形成一個完整的單詞。 它還包含一個布爾指示符,以顯示這是否是最后一個字母。
Trie具有以下方法:
· add:在字典樹中插入一個單詞
· isWord:確定樹是否由某些單詞組成
· print:返回樹中的所有單詞
/** Node in Trie **/ function Node() { = new Map(); = false; = function () { = true; }; = function () { return ; } } function Trie() { = new Node(); = function (input, node = ) { if === 0) { node.setEnd(); return; } else if (!node.keys.has(input[0])) { node.keys.set(input[0], new Node()); return (1), node.keys.get(input[0])); } else { return (1), node.keys.get(input[0])); } } = function (word) { let node = ; while > 1) { if (!node.keys.has(word[0])) { return false; } else { node = node.keys.get(word[0]); word = word.substr(1); } } return (word) && node.keys.get(word).isEnd()) ? true : false; } = function () { let words = new Array(); let search = function (node = , string) { if != 0) { for (let letter of node.keys.keys()) { searc(letter), (letter)); } if ()) { words.push(string); } } else { > 0 ? words.push(string) : undefined; return; } }; search(, new String()); return words.length > 0 ? words : null; } }8.圖
圖(有時稱為網(wǎng)絡(luò))是指具有鏈接(或邊)的節(jié)點集。 根據(jù)鏈接是否具有方向,它可以進一步分為兩組(即有向圖和無向圖)。 Graph在我們的生活中得到了廣泛使用,例如,在導(dǎo)航應(yīng)用中計算最佳路線,或者在社交媒體中向推薦的朋友舉兩個例子。
圖有兩種表示形式:
鄰接表
在此方法中,我們在左側(cè)列出所有可能的節(jié)點,并在右側(cè)顯示已連接的節(jié)點。
鄰接矩陣
鄰接矩陣顯示行和列中的節(jié)點,行和列的交點解釋節(jié)點之間的關(guān)系,0表示未鏈接,1表示鏈接,> 1表示不同的權(quán)重。
要查詢圖中的節(jié)點,必須使用"廣度優(yōu)先"(BFS)方法或"深度優(yōu)先"(DFS)方法在整個樹形網(wǎng)絡(luò)中進行搜索。
讓我們看一個用Javascript編寫B(tài)FS的示例:
function bfs(graph, root) { var nodesLen = {}; for (var i = 0; i < gra; i++) { nodesLen[i] = Infinity; } nodesLen[root] = 0; var queue = [root]; var current; while != 0) { current = queue.shift(); var curConnected = graph[current]; var neighborIdx = []; var idx = curConnec(1); while (idx != -1) { neig(idx); idx = curConnec(1, idx + 1); } for (var j = 0; j < neig; j++) { if (nodesLen[neighborIdx[j]] == Infinity) { nodesLen[neighborIdx[j]] = nodesLen[current] + 1; queue.push(neighborIdx[j]); } } } return nodesLen; }測試一下:
var graph = [ [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [1, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 1, 0, 0, 0] ]; con(bfs(graph, 1));結(jié)果:
{ 0: 2, 1: 0, 2: 1, 3: 3, 4: Infinity }就是這樣–我們涵蓋了所有常見的數(shù)據(jù)結(jié)構(gòu),并提供了JavaScript中的示例。 這應(yīng)該使您更好地了解計算機中數(shù)據(jù)結(jié)構(gòu)的工作方式。 編碼愉快!
(本文翻譯自Kingsley Tan的文章《8 Common Data Structures in Javascript》, 參考 )
1.《【crixus】JavaScript的八種常見數(shù)據(jù)結(jié)構(gòu)》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《【crixus】JavaScript的八種常見數(shù)據(jù)結(jié)構(gòu)》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/yule/2254751.html