在 JavaScript 里,數據結構和算法是十分關鍵的部分,下面介紹幾種常見的數據結構和對應的算法。
-
數組(Array)
數組是最基礎的數據結構,用于存儲一系列有序的數據。// 創建數組 const arr = [1, 2, 3, 4, 5];// 訪問元素 console.log(arr[0]); // 輸出 1// 修改元素 arr[0] = 10; console.log(arr); // 輸出 [10, 2, 3, 4, 5]// 遍歷數組 for (let i = 0; i < arr.length; i++) {console.log(arr[i]); }
-
棧(Stack)
棧是一種后進先出(LIFO)的數據結構,僅能在棧頂進行插入和刪除操作。class Stack {constructor() {this.items = [];}// 入棧push(element) {this.items.push(element);}// 出棧pop() {if (this.isEmpty()) {return null;}return this.items.pop();}// 獲取棧頂元素peek() {if (this.isEmpty()) {return null;}return this.items[this.items.length - 1];}// 判斷棧是否為空isEmpty() {return this.items.length === 0;}// 獲取棧的大小size() {return this.items.length;} }// 使用棧 const stack = new Stack(); stack.push(1); stack.push(2); console.log(stack.pop()); // 輸出 2
-
隊列(Queue)
隊列是一種先進先出(FIFO)的數據結構,元素從隊尾入隊,從隊頭出隊。class Queue {constructor() {this.items = [];}// 入隊enqueue(element) {this.items.push(element);}// 出隊dequeue() {if (this.isEmpty()) {return null;}return this.items.shift();}// 獲取隊頭元素front() {if (this.isEmpty()) {return null;}return this.items[0];}// 判斷隊列是否為空isEmpty() {return this.items.length === 0;}// 獲取隊列的大小size() {return this.items.length;}// 清空隊列clear() {this.items = [];} }// 使用隊列 const queue = new Queue(); queue.enqueue(1); queue.enqueue(2); console.log(queue.dequeue()); // 輸出 1
-
鏈表(Linked List)
鏈表是由節點構成的數據結構,每個節點包含數據和指向下一個節點的指針。class Node {constructor(data) {this.data = data;this.next = null;} }class LinkedList {constructor() {this.head = null;this.length = 0;}// 在鏈表尾部添加節點append(data) {const newNode = new Node(data);if (this.head === null) {this.head = newNode;} else {let current = this.head;while (current.next !== null) {current = current.next;}current.next = newNode;}this.length++;}// 打印鏈表print() {let current = this.head;const result = [];while (current !== null) {result.push(current.data);current = current.next;}console.log(result.join(' -> '));} }// 使用鏈表 const linkedList = new LinkedList(); linkedList.append(1); linkedList.append(2); linkedList.print(); // 輸出 1 -> 2
-
排序算法 - 冒泡排序(Bubble Sort)
冒泡排序是一種簡單的排序算法,它重復地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把它們交換過來。function bubbleSort(arr) {const len = arr.length;for (let i = 0; i < len - 1; i++) {for (let j = 0; j < len - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交換元素[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];}}}return arr; }const unsortedArray = [5, 3, 8, 4, 2]; const sortedArray = bubbleSort(unsortedArray); console.log(sortedArray); // 輸出 [2, 3, 4, 5, 8]
-
二叉樹
二叉樹是每個節點最多有兩個子節點的樹結構,這兩個子節點通常被稱為左子節點和右子節點。// 二叉樹節點類 class TreeNode {constructor(value) {// 節點存儲的值this.value = value;// 左子節點,初始為 nullthis.left = null;// 右子節點,初始為 nullthis.right = null;} } // 創建根節點 const root = new TreeNode(1); // 為根節點添加左子節點 root.left = new TreeNode(2); // 為根節點添加右子節點 root.right = new TreeNode(3); // 為左子節點添加左子節點 root.left.left = new TreeNode(4); // 為左子節點添加右子節點 root.left.right = new TreeNode(5);// 前序遍歷 function preOrderTraversal(node) {if (node === null) {return;}console.log(node.value);preOrderTraversal(node.left);preOrderTraversal(node.right); } // 對上述構建的二叉樹進行前序遍歷 preOrderTraversal(root);// 中序遍歷 function inOrderTraversal(node) {if (node === null) {return;}inOrderTraversal(node.left);console.log(node.value);inOrderTraversal(node.right); } // 對上述構建的二叉樹進行中序遍歷 inOrderTraversal(root);// 后續遍歷 function postOrderTraversal(node) {if (node === null) {return;}postOrderTraversal(node.left);postOrderTraversal(node.right);console.log(node.value); } // 對上述構建的二叉樹進行后序遍歷 postOrderTraversal(root);// 層序遍歷 function levelOrderTraversal(root) {if (root === null) {return;}const queue = [root];while (queue.length > 0) {const current = queue.shift();console.log(current.value);if (current.left!== null) {queue.push(current.left);}if (current.right!== null) {queue.push(current.right);}} } // 對上述構建的二叉樹進行層序遍歷 levelOrderTraversal(root);
二叉樹是一種靈活且強大的數據結構,不同的遍歷方式適用于不同的場景。前序遍歷常用于復制二叉樹、表達式樹求值;中序遍歷常用于二叉搜索樹的排序輸出;后序遍歷常用于釋放二叉樹的節點內存;層序遍歷常用于按層次訪問節點。