JS面試之函數(1)
JS面試之對象(2)
JS面試之數組的幾個不low操做(3)
JS面試之http0.9~3.0對比分析(4)node
數據結構是計算機存儲、組織數據的方式,算法是系統描述解決問題的策略。瞭解基本的數據結構和算法能夠提升代碼的性能和質量。
也是程序猿進階的一個重要技能。
手擼代碼實現棧,隊列,鏈表,字典,二叉樹,動態規劃和貪心算法
棧的特色:先進後出面試
class Stack { constructor() { this.items = []; } // 入棧 push(element) { this.items.push(element); } // 出棧 pop() { return this.items.pop(); } // 末位 get peek() { return this.items[this.items.length - 1]; } // 是否爲空棧 get isEmpty() { return !this.items.length; } // 長度 get size() { return this.items.length; } // 清空棧 clear() { this.items = []; } } // 實例化一個棧 const stack = new Stack(); console.log(stack.isEmpty); // true // 添加元素 stack.push(5); stack.push(8); // 讀取屬性再添加 console.log(stack.peek); // 8 stack.push(11); console.log(stack.size); // 3 console.log(stack.isEmpty); // false
隊列:先進先出算法
class Queue { constructor(items) { this.items = items || []; } enqueue(element) { this.items.push(element); } dequeue() { return this.items.shift(); } front() { return this.items[0]; } clear() { this.items = []; } get size() { return this.items.length; } get isEmpty() { return !this.items.length; } print() { console.log(this.items.toString()); } } const queue = new Queue(); console.log(queue.isEmpty); // true queue.enqueue("John"); queue.enqueue("Jack"); queue.enqueue("Camila"); console.log(queue.size); // 3 console.log(queue.isEmpty); // false queue.dequeue(); queue.dequeue();
鏈表:存貯有序元素的集合,
可是不一樣於數組,每一個元素是一個存貯元素自己的節點和指向下一個元素引用組成
要想訪問鏈表中間的元素,須要從起點開始遍歷找到所需元素segmentfault
class Node { constructor(element) { this.element = element; this.next = null; } } // 鏈表 class LinkedList { constructor() { this.head = null; this.length = 0; } // 追加元素 append(element) { const node = new Node(element); let current = null; if (this.head === null) { this.head = node; } else { current = this.head; while (current.next) { current = current.next; } current.next = node; } this.length++; } // 任意位置插入元素 insert(position, element) { if (position >= 0 && position <= this.length) { const node = new Node(element); let current = this.head; let previous = null; let index = 0; if (position === 0) { this.head = node; } else { while (index++ < position) { previous = current; current = current.next; } node.next = current; previous.next = node; } this.length++; return true; } return false; } // 移除指定位置元素 removeAt(position) { // 檢查越界值 if (position > -1 && position < length) { let current = this.head; let previous = null; let index = 0; if (position === 0) { this.head = current.next; } else { while (index++ < position) { previous = current; current = current.next; } previous.next = current.next; } this.length--; return current.element; } return null; } // 尋找元素下標 findIndex(element) { let current = this.head; let index = -1; while (current) { if (element === current.element) { return index + 1; } index++; current = current.next; } return -1; } // 刪除指定文檔 remove(element) { const index = this.indexOf(element); return this.removeAt(index); } isEmpty() { return !this.length; } size() { return this.length; } // 轉爲字符串 toString() { let current = this.head; let string = ""; while (current) { string += ` ${current.element}`; current = current.next; } return string; } } const linkedList = new LinkedList(); console.log(linkedList); linkedList.append(2); linkedList.append(6); linkedList.append(24); linkedList.append(152); linkedList.insert(3, 18); console.log(linkedList); console.log(linkedList.findIndex(24));
字典:相似對象,以key,value存貯值數組
class Dictionary { constructor() { this.items = {}; } set(key, value) { this.items[key] = value; } get(key) { return this.items[key]; } remove(key) { delete this.items[key]; } get keys() { return Object.keys(this.items); } get values() { /* 也能夠使用ES7中的values方法 return Object.values(this.items) */ // 在這裏咱們經過循環生成一個數組並輸出 return Object.keys(this.items).reduce((r, c, i) => { r.push(this.items[c]); return r; }, []); } } const dictionary = new Dictionary(); dictionary.set("Gandalf", "gandalf@email.com"); dictionary.set("John", "johnsnow@email.com"); dictionary.set("Tyrion", "tyrion@email.com"); console.log(dictionary); console.log(dictionary.keys); console.log(dictionary.values); console.log(dictionary.items);
特色:每一個節點最多有兩個子樹的樹結構數據結構
class NodeTree { constructor(key) { this.key = key; this.left = null; this.right = null; } } class BinarySearchTree { constructor() { this.root = null; } insert(key) { const newNode = new NodeTree(key); const insertNode = (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); } } }; if (!this.root) { this.root = newNode; } else { insertNode(this.root, newNode); } } //訪問樹節點的三種方式:中序,先序,後序 inOrderTraverse(callback) { const inOrderTraverseNode = (node, callback) => { if (node !== null) { inOrderTraverseNode(node.left, callback); callback(node.key); inOrderTraverseNode(node.right, callback); } }; inOrderTraverseNode(this.root, callback); } min(node) { const minNode = node => { return node ? (node.left ? minNode(node.left) : node) : null; }; return minNode(node || this.root); } max(node) { const maxNode = node => { return node ? (node.right ? maxNode(node.right) : node) : null; }; return maxNode(node || this.root); } } const tree = new BinarySearchTree(); tree.insert(11); tree.insert(7); tree.insert(5); tree.insert(3); tree.insert(9); tree.insert(8); tree.insert(10); tree.insert(13); tree.insert(12); tree.insert(14); tree.inOrderTraverse(value => { console.log(value); }); console.log(tree.min()); console.log(tree.max());
冒泡排序,選擇排序,插入排序,此處不作贅述,請戳 排序app
特色:第三項等於前面兩項之和數據結構和算法
function fibonacci(num) { if (num === 1 || num === 2) { return 1 } return fibonacci(num - 1) + fibonacci(num - 2) }
特色:經過全局規劃,將大問題分割成小問題來取最優解
案例:最少硬幣找零
美國有如下面額(硬幣):d1=1, d2=5, d3=10, d4=25
若是要找36美分的零錢,咱們能夠用1個25美分、1個10美分和1個便士( 1美分)函數
class MinCoinChange { constructor(coins) { this.coins = coins this.cache = {} } makeChange(amount) { if (!amount) return [] if (this.cache[amount]) return this.cache[amount] let min = [], newMin, newAmount this.coins.forEach(coin => { newAmount = amount - coin if (newAmount >= 0) { newMin = this.makeChange(newAmount) } if (newAmount >= 0 && (newMin.length < min.length - 1 || !min.length) && (newMin.length || !newAmount)) { min = [coin].concat(newMin) } }) return (this.cache[amount] = min) } } const rninCoinChange = new MinCoinChange([1, 5, 10, 25]) console.log(rninCoinChange.makeChange(36)) // [1, 10, 25] const minCoinChange2 = new MinCoinChange([1, 3, 4]) console.log(minCoinChange2.makeChange(6)) // [3, 3]
特色:經過最優解來解決問題
用貪心算法來解決2.3中的案例性能
class MinCoinChange2 { constructor(coins) { this.coins = coins } makeChange(amount) { const change = [] let total = 0 this.coins.sort((a, b) => a < b).forEach(coin => { if ((total + coin) <= amount) { change.push(coin) total += coin } }) return change } } const rninCoinChange2 = new MinCoinChange2 ( [ 1, 5, 10, 25]) console.log (rninCoinChange2. makeChange (36))