摘要:數(shù)據(jù)結(jié)構(gòu)數(shù)組方法一數(shù)組添加元素開頭插入尾部刪除頭部刪除數(shù)組合并迭代器方法會迭代數(shù)組中每個元素,直到返回。這個數(shù)據(jù)結(jié)構(gòu)使用了與有限集合相同的數(shù)學(xué)概念,但應(yīng)用在計算機(jī)科學(xué)的數(shù)據(jù)結(jié)構(gòu)中。散列算法的作用是盡可能快的在數(shù)據(jù)結(jié)構(gòu)中找到一個值。
數(shù)據(jù)結(jié)構(gòu) 數(shù)組 方法
//一、數(shù)組 var arr = []; // 添加元素 arr.push(1, 2); // [1,2] // 開頭插入 arr.unshift(0); // [0, 1, 3] // 尾部刪除 arr.pop(); // [0, 1] // 頭部刪除 arr.shift(); // [1] // 數(shù)組合并 [1].concat([2]) // [1,2]迭代器
every every方法會迭代數(shù)組中每個元素,直到返回false。
some some和every類似,不過some方法會迭代數(shù)組的每個元素,直到函數(shù)返回true
forEach 和for循環(huán)的結(jié)果相同
map 返回新的數(shù)組 [1,2].map(o => o * 2) // [2,4]
filter 返回新的數(shù)組 [1,2].filter(o => o > 1) // [2]
reduce [1,2].reduce((result, current) => result + current) // 3
for of for (let n of numbers) { console.log((n % 2 === 0) ? "even" : "odd")};
entries
const numbers = [1,2,3]; let aEntries = numbers.entries(); // 得到鍵值對的迭代器 console.log(aEntries.next().value); // [0, 1] 位置0的值為1 console.log(aEntries.next().value); // [1, 2] 位置1的值為2 console.log(aEntries.next().value); // [2, 3] 位置2的值為3
keys
const numbers = [1,2,3]; console.log(Object.keys(numbers)); // ["0","1","2"];
values
const numbers = [1,2,3]; console.log(Object.values(numbers)); // [1,2,3]
Array.from
Array.of
fill
copyWithin
sort
find
findIndex
includes
棧棧是一種遵從后進(jìn)先出原則的有序集合實現(xiàn)
function Stack() { let items = []; // 向棧添加元素 this.push = function(element) { items.push(element); } // 從棧移除元素 this.pop = function() { return items.pop(); }; // 查看棧頂元素 this.peek = function() { return items[item.length - 1]; } // 檢查棧是否為空 this.isEmpty = function() { return items.length == 0; } this.size = function() { return items.length; }; // 清空和打印棧元素 this.clear = function() { items = []; }; this.print = function() { console.log(items.toString()); }; }用棧解決問題
存儲訪問過的任務(wù)或路徑、撤銷的操作等。
隊列隊列是遵循FIFO(First In First Out, 先進(jìn)先出,也稱為先來先服務(wù))實現(xiàn)
function Queue() { let items = []; // 向隊列添加元素 this.enqueue = function(element) { items.push(element); }; // 從隊列移除元素 this.dequeue = function() { return items.shift(); }; // 查看隊列頭元素 this.front = function() { return items[0]; }; // 檢查隊列是否為空 this.isEmpty = function() { return items.length == 0; }; this.size = function() { return items.length; }; // 打印隊列元素 this.print = function() { console.log(items.toString()); }; }鏈表
鏈表村粗有序的元素集合,但不同于數(shù)組,鏈表中的元素在內(nèi)存中并不是連續(xù)放置的。每個元素由一個存儲元素本身的節(jié)點和一個指向下一個元素的引用(也稱指針或鏈接)組成。實現(xiàn)
相對于傳統(tǒng)的數(shù)組,鏈表的一個好處在于,添加或移除元素的時候不需要移動其他元素。然而,鏈表需要使用指針,因此實現(xiàn)鏈表時需要額外注意。數(shù)組的另一個細(xì)節(jié)是可以直接訪問任何位置的任何元素,而要想訪問鏈表中間的一個元素,需要從起點(表頭)開始迭代列表直到找到所需的元素。
function LinkedList() { let Node = function(element) { this.element = element; this.next = null; }; let length = 0; let head = null; // 向鏈表尾部追加元素 this.append = function(element) { let node = new Node(element), current; if (head === null) { head = node; } else { current = head; // 循環(huán)列表,直到找到最后一項 while (current.next) { current = current.next; } // 找到最后一項,將其next賦為node,建立鏈接 current.next = node; } length++; // 更新列表的長度 } // 從鏈表中移除元素 this.removeAt = function() { // 檢查越界值 if (position > -1 && position < length) { let current = head, previous, index = 0; // 移除第一項 if (position === 0) { head = current.next; } else { while (index++ < position) { previous = current; current = current.next; } // 將previous 與 current的下一項鏈接起來: 跳過current,從而移除它 previous.next = current.next; } length--; return current.element; } else { return null; } } // 在任意位置插入元素 this.insert = function(position, element) { // 檢查越界值 if (position >= 0 && position <= length) { let node = new Node(element), current = head, previous, index = 0; if (position === 0) { // 在第一個位置添加 node.next = current; head = node; } else { while (index++ < position) { previous = current; current = current.next; } node.next = current; previous.next = node; } length++; // 更新列表的長度 return true; } else { return false; } } // toString方法 this.toString = function() { let current = head, string = ""; while (current) { string += current.element + (current.next ? "n" : ""); current = current.next; } return string; } // indexOf 方法 this.indexOf = function(elment) { let current = head, index = 0; while(current) { if (element === current.element) { return index; } index++; current = current.next; } return -1; } // remove 方法 this.remove = function(elment) { let index = this.indexOf(element); return this.removeAt(index); } // isEmpty 方法 this.isEmpty = function() { return length == 0; } // size 方法 this.size = function() { return length; } // getHead 方法 this.getHead = function() { return head; } }雙向鏈表(留給大家自己思考) 集合
集合是由一組無序且唯一(即不能重復(fù))的項組合的。這個數(shù)據(jù)結(jié)構(gòu)使用了與有限集合相同的數(shù)學(xué)概念,但應(yīng)用在計算機(jī)科學(xué)的數(shù)據(jù)結(jié)構(gòu)中。
function Set() { let items = {}; // has 方法 this.has = function(value) { return items.hasOwnProperty(value); }; // add 方法 this.add = function(value) { if (!this.has(value)) { items[value] = value; return true; } return false; } // remove 方法 this.remove = function(value) { if (this.has(value)) { delete items[value]; return true; } return false; } // clear 方法 this.clear = function() { items = {}; } // size 方法 this.size = function() { return Object.keys(items).length; } // values 方法 this.values = function() { let values = []; for (let i = 0, keys = Object.keys(items); i< keys.length; i++) { values.push(items[keys[i]]); } return values; } // 并集 this.union = function(otherSet) { let unionSet = new Set(); let values = this.values(); for (let i = 0; i < values.length; i++) { unionSet.add(values[i]); } values = otherSet.values(); for (let i = 0; i < values.length; i++) { unionSet.add(values[i]); } return unionSet; } // 交集 this.intersection = function(otherSet) { let intersectionSet = new Set(); let values = this.values(); for (let i = 0;i字典和散列表 實現(xiàn)otherSet.size()) { return false; } else { let values = this.values(); for (let i = 0;i< values.length;i++) { if (!otherSet.has(values[i])) { return false; } } return true; } } }
function Dictionary() { var items = {}; // has 和 set 方法 this.has = function(key) { return items.hasOwnProperty(key); } this.set = function(key, value) { item[key] = value; } // delete 方法 this.delete = function(key) { if (this.has(key)) { delete items[key]; return true; } return false; } // get 和 values 方法 this.get = function(key) { return this.has(key) ? items[key] : undefined; } this.values = function() { var values = []; for(var k in items) { if (this.has(k)) { values.push(items[k]); } } return values; } // clear 方法 this.clear = function() { items = {}; } // size 方法 this.size = function() { return Object.keys(items).length; } // keys 方法 this.keys = function() { return Object.keys(items); } // getItems 方法 this.getItems = function() { return items; } }散列表
HashTable類 也叫 HashMap類,它是Dictionary類的一種散列表是實現(xiàn)方式。
散列算法的作用是盡可能快的在數(shù)據(jù)結(jié)構(gòu)中找到一個值。
function HashTable() { var table = []; var loseloseHashCode = function(key) { var hash = 0; for (var i = 0; i< key.length; i++) { hash += key.charCodeAt(i); } return hash % 37; } this.put = function(key, value) { var position = loseloseHashCode(key); console.log(position + " - " + key); table[position] = value; } this.get = function(key) { return table[loseloseHashCode(key)]; } this.remove = function(key) { table[loseloseHashCode(key)] = undefined; } }Map類
es6 新增了Map類
var map = new Map(); map.set("a", "b"); console.log(map.has("a")); // true console.log(map.size()); // 輸出1 console.log(map.keys()); // ["a"] console.log(map.values()); // ["b"]; // 和Dictionary類不同,es6的Map類的values方法和keys方法都返回Iterator,而不是值或鍵構(gòu)成的數(shù)組。es6 --- WeakMap類 和 WeakSet類
WeakMap 和 WeakSet類沒有entries keys values等方法
只能用對象作為鍵
var map = new WeakMap(); var obj = {name: "a"}; map.set(obj, "b"); console.log(map.has(obj)); // 輸出true console.log(map.get(obj)); // 輸入"b" map.delete(obj);樹
一個樹結(jié)構(gòu)包含一系列存在父子關(guān)系的節(jié)點。每個節(jié)點都有一個父節(jié)點(除了頂部的第一個節(jié)點)以及零個或多個子節(jié)點;二叉樹和二叉搜索樹
function BinarySearchTree() { var Node = function(key) { this.key = key; this.left = null; this.right = null; } var root = null; var insertNode = function(node, newNode) { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode; } else { insertNode(node.left, newNode); } } else { if (node.right === null) { node.right = newNode; } else { insertNode(node.right, newNode); } } } // 向樹中插入一個鍵 this.insert = function(key) { var newNode = new Node(key); if (root = null) { root = newNode; } else { insertNode(root, newNode); } } var inOrderTraverseNode = function(node, callback) { if (node !== null) { inOrderTraverseNode(node.left, callback); callback(node.key); inOrderTraverseNode(node.right, callback); } } // 中序遍歷 this.inOrderTraverse = function(callback) { inOrderTraverseNode(root, callback); } var preOrderTraverseNode = function(node, callback) { if (node !== null) { callback(node.key); preOrderTraverseNode(node.left, callback); preOrderTraverseNode(node.right, callback); } } // 先序遍歷 this.preOrderTraverse = function(callback) { preOrderTraverseNode(root, callback); } var postOrderTraverseNode = function(node, callback) { if (node !== null) { postOrderTraverseNode(node.left, callback); postOrderTraverseNode(node.right, callback); callback(node.key); } } // 后序遍歷 this.postOrderTraverse = function(callback) { postOrderTraverseNode(root, callback); } // 搜索最小值 this.min = function() { return minNode(root); } var minNode = function(node) { if (node) { while( node && node.left !== null) { node = node.left; } return node.key; } return null; } // 搜索最大值 this.max = function() { return maxNode(root); } var maxNode = function(node) { if (node) { while(node && node.right !== null) { node = node.right; } return node.key; } return null; } // 搜索一個特定的值 this.search = function(key) { return searchNode(root, key); } var searchNode = function(node, key) { if (node === null) { return false; } if (key < node.key) { return searchNode(node.left, key); } else if (key > node.key) { return searchNode(node.right, key); } else { return true; } } // 移除一個節(jié)點 this.remove = function(key) { root = removeNode(root, key); } var removeNode = function(node, key) { if (node === null) { return null; } if (key < node.key) { node.left = removeNode(node.left,key); return node; } else if (key > node.key) { node.right = removeNode(node.right,key); return node; } else { // 鍵等于node.key // 第一種情況--一個葉節(jié)點 if (node.left === null && node.right === null) { node = null; return node; } // 第二種情況--一個只有一個子節(jié)點的節(jié)點 if (node.left === null) { node = node.right; return node; } else if (node.right === null) { node = node.left; return node; } // 第三種情況---- 一個有兩個子節(jié)點的節(jié)點 var aux = findMinNode(node.right); node.key = aux.key; node.right = removeNode(node.rihgt, aux.key); return node; } var findMinNode = function(node) { while (node && node.left !== null) { node = node.left; } return node; } } }自平衡樹(AVL)
當(dāng)樹很深的時候,添加移除和搜索某個節(jié)點時引起一些性能問題。
var heightNode = function(node) { if (node === null) { return -1; } else { return Math.max(heightNode(node.left), heightNode(node.right)) + 1; } } var rotationRR = function(node) { var tmp = node.right; node.right = tmp.left; tmp.left = node; return tmp; } var rotationLL = function(node) { var tmp = node.left; node.left = tmp.right; tmp.right = node; return tmp; } var rotationLR = function(node) { node.left = rotationRR(node.left); return rotationLL(node); } var rotationRL = function(node) { node.right = rotationLL(node.right); return rotationRR(node); } var insertNode = function(node, element) { if (node === null) { node = new Node(element); } else if (element < node.key) { node.left = insertNode(node.left, element); if (node.left !== null) { // 確認(rèn)是否需要平衡 if ((heightNode(node.left) - heightNode(node.right) > 1)) { if (element < node.left.key) { node = rotationLL(node); } else { node = rotationLR(node); } } } } else if (element > node.key) { node.right = insertNode(node.right, element); if (node.right !== null) { // 確認(rèn)是否需要平衡 if ((heightNode(node.right) - heightNode(node.left) > 1)) { if (element > node.right.key) { node = rotationRR(node); } else { node = rotationRL(node); } } } } return node; }圖
圖是網(wǎng)絡(luò)結(jié)構(gòu)的抽象模型,圖是一組由邊連接的節(jié)點(或頂點)。學(xué)習(xí)圖是重要的,因為任何關(guān)系都可以用圖來表示
function Graph() { var vertices = []; var adjList = new Dictionary(); this.addVertex = function(v) { vartices.push(v); adjList.set(v, []); } this.addEdge = function(v, w) { addList.get(v).push(w); addList.get(w).push(v); } this.toString = function() { var s = ""; for (var i = 0; i< vertices.length;i++) { s += vertices[i] + " -> "; var neighbors = adjList.get(vertices[i]); for (var j = 0;j
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102335.html
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢?dǎo)致有不是面向?qū)ο筮@樣的說法。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些...
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢?dǎo)致有不是面向?qū)ο筮@樣的說法。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些...
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢?dǎo)致有不是面向?qū)ο筮@樣的說法。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些...
摘要:網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知識點羅列為主或是資料的匯總,數(shù)據(jù)量讓新人望而卻步。天了解一個前端框架。也可以關(guān)注微信公眾號曉舟報告,發(fā)送獲取資料,就能收到下載密碼,網(wǎng)盤地址在最下方,獲取教程和案例的資料。 前言 好的學(xué)習(xí)方法可以事半功倍,好的學(xué)習(xí)路徑可以指明前進(jìn)方向。這篇文章不僅要寫學(xué)習(xí)路徑,還要寫學(xué)習(xí)方法,還要發(fā)資料,干貨滿滿,準(zhǔn)備接招。 網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知...
摘要:元素,當(dāng)瀏覽器不支持腳本數(shù)據(jù)結(jié)構(gòu)有如下中基本數(shù)據(jù)結(jié)構(gòu)操作符,用來檢測給定變量的數(shù)據(jù)類型結(jié)果都是,聲明沒初始化,使用生命變量但未對其進(jìn)行初始化的,默認(rèn)沒有進(jìn)行聲明,傳遞給函數(shù)會導(dǎo)致一個錯誤,對于未聲明變量這么操作沒什么意義比如,也是返回。 javascript簡史 微軟IE和網(wǎng)景在瀏覽器上的競爭 ECMAScript,由ECMA-262定義,提供核心語言功能 `ECMA 歐洲計算機(jī)制...
閱讀 1354·2019-08-30 15:44
閱讀 2098·2019-08-30 11:04
閱讀 517·2019-08-29 15:17
閱讀 2539·2019-08-26 12:12
閱讀 3131·2019-08-23 18:09
閱讀 921·2019-08-23 15:37
閱讀 1521·2019-08-23 14:43
閱讀 2920·2019-08-23 13:13