diff --git a/.gitignore b/.gitignore index 3ff305496..e93873c95 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,5 @@ docs/overrides/ # python files __pycache__ -# iml -hello-algo.iml +# in-progress articles +docs/chapter_heap diff --git a/codes/cpp/chapter_tree/binary_tree_bfs.cpp b/codes/cpp/chapter_tree/binary_tree_bfs.cpp index 236f62449..ffc2e372c 100644 --- a/codes/cpp/chapter_tree/binary_tree_bfs.cpp +++ b/codes/cpp/chapter_tree/binary_tree_bfs.cpp @@ -30,8 +30,7 @@ vector hierOrder(TreeNode* root) { int main() { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode* root = vecToTree(vector - { 1, 2, 3, 4, 5, 6, 7, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX }); + TreeNode* root = vecToTree(vector { 1, 2, 3, 4, 5, 6, 7 }); cout << endl << "初始化二叉树\n" << endl; PrintUtil::printTree(root); diff --git a/codes/cpp/chapter_tree/binary_tree_dfs.cpp b/codes/cpp/chapter_tree/binary_tree_dfs.cpp index 51287b736..5ed5b78fe 100644 --- a/codes/cpp/chapter_tree/binary_tree_dfs.cpp +++ b/codes/cpp/chapter_tree/binary_tree_dfs.cpp @@ -41,8 +41,7 @@ void postOrder(TreeNode* root) { int main() { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode* root = vecToTree(vector - { 1, 2, 3, 4, 5, 6, 7, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX}); + TreeNode* root = vecToTree(vector { 1, 2, 3, 4, 5, 6, 7 }); cout << endl << "初始化二叉树\n" << endl; PrintUtil::printTree(root); diff --git a/codes/cpp/include/TreeNode.hpp b/codes/cpp/include/TreeNode.hpp index ab54c7746..82f2ce981 100644 --- a/codes/cpp/include/TreeNode.hpp +++ b/codes/cpp/include/TreeNode.hpp @@ -27,23 +27,24 @@ struct TreeNode { * @return TreeNode* */ TreeNode *vecToTree(vector list) { - if (list.empty()) { + if (list.empty()) return nullptr; - } auto *root = new TreeNode(list[0]); queue que; - size_t n = list.size(), index = 1; - while (index < n) { + que.emplace(root); + size_t n = list.size(), index = 0; + while (!que.empty()) { auto node = que.front(); que.pop(); - + if (++index >= n) break; if (index < n) { - node->left = new TreeNode(list[index++]); + node->left = new TreeNode(list[index]); que.emplace(node->left); } + if (++index >= n) break; if (index < n) { - node->right = new TreeNode(list[index++]); + node->right = new TreeNode(list[index]); que.emplace(node->right); } } diff --git a/codes/csharp/chapter_tree/binary_tree_bfs.cs b/codes/csharp/chapter_tree/binary_tree_bfs.cs index 31f707246..f0c914acb 100644 --- a/codes/csharp/chapter_tree/binary_tree_bfs.cs +++ b/codes/csharp/chapter_tree/binary_tree_bfs.cs @@ -41,8 +41,7 @@ namespace hello_algo.chapter_tree { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode? root = TreeNode.ArrToTree(new int?[] { - 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null}); + TreeNode? root = TreeNode.ArrToTree(new int?[] { 1, 2, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树\n"); PrintUtil.PrintTree(root); diff --git a/codes/csharp/chapter_tree/binary_tree_dfs.cs b/codes/csharp/chapter_tree/binary_tree_dfs.cs index 6e38ebe4c..0f89cb3b2 100644 --- a/codes/csharp/chapter_tree/binary_tree_dfs.cs +++ b/codes/csharp/chapter_tree/binary_tree_dfs.cs @@ -57,8 +57,7 @@ namespace hello_algo.chapter_tree { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode? root = TreeNode.ArrToTree(new int?[] { - 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null}); + TreeNode? root = TreeNode.ArrToTree(new int?[] { 1, 2, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树\n"); PrintUtil.PrintTree(root); diff --git a/codes/csharp/include/TreeNode.cs b/codes/csharp/include/TreeNode.cs index e5cacd59e..9cd0ac92c 100644 --- a/codes/csharp/include/TreeNode.cs +++ b/codes/csharp/include/TreeNode.cs @@ -19,7 +19,7 @@ namespace hello_algo.include } /** - * Generate a binary tree with an array + * Generate a binary tree given an array * @param arr * @return */ @@ -31,22 +31,22 @@ namespace hello_algo.include TreeNode root = new TreeNode((int) arr[0]); Queue queue = new Queue(); queue.Enqueue(root); - int i = 1; - while (queue.Count!=0) + int i = 0; + while (queue.Count != 0) { TreeNode node = queue.Dequeue(); + if (++i >= arr.Length) break; if (arr[i] != null) { node.left = new TreeNode((int) arr[i]); queue.Enqueue(node.left); } - i++; + if (++i >= arr.Length) break; if (arr[i] != null) { node.right = new TreeNode((int) arr[i]); queue.Enqueue(node.right); } - i++; } return root; } diff --git a/codes/go/chapter_tree/binary_tree_bfs_test.go b/codes/go/chapter_tree/binary_tree_bfs_test.go index 8d5c0aaff..d32dbdca9 100644 --- a/codes/go/chapter_tree/binary_tree_bfs_test.go +++ b/codes/go/chapter_tree/binary_tree_bfs_test.go @@ -14,11 +14,11 @@ import ( func TestLevelOrder(t *testing.T) { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - root := ArrayToTree([]int{1, 2, 3, 4, 5, 6, 7}) - fmt.Println("初始化二叉树: ") + root := ArrToTree([]int{1, 2, 3, 4, 5, 6, 7}) + fmt.Println("\n初始化二叉树: ") PrintTree(root) // 层序遍历 nums := levelOrder(root) - fmt.Println("层序遍历的结点打印序列 =", nums) + fmt.Println("\n层序遍历的结点打印序列 =", nums) } diff --git a/codes/go/chapter_tree/binary_tree_dfs_test.go b/codes/go/chapter_tree/binary_tree_dfs_test.go index 67a3e1f3a..b0db8086c 100644 --- a/codes/go/chapter_tree/binary_tree_dfs_test.go +++ b/codes/go/chapter_tree/binary_tree_dfs_test.go @@ -14,22 +14,22 @@ import ( func TestPreInPostOrderTraversal(t *testing.T) { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - root := ArrayToTree([]int{1, 2, 3, 4, 5, 6, 7}) - fmt.Println("初始化二叉树: ") + root := ArrToTree([]int{1, 2, 3, 4, 5, 6, 7}) + fmt.Println("\n初始化二叉树: ") PrintTree(root) // 前序遍历 nums = nil preOrder(root) - fmt.Println("前序遍历的结点打印序列 =", nums) + fmt.Println("\n前序遍历的结点打印序列 =", nums) // 中序遍历 nums = nil inOrder(root) - fmt.Println("中序遍历的结点打印序列 =", nums) + fmt.Println("\n中序遍历的结点打印序列 =", nums) // 后序遍历 nums = nil postOrder(root) - fmt.Println("后序遍历的结点打印序列 =", nums) + fmt.Println("\n后序遍历的结点打印序列 =", nums) } diff --git a/codes/go/pkg/tree_node.go b/codes/go/pkg/tree_node.go index 2511a7655..b1e630e67 100644 --- a/codes/go/pkg/tree_node.go +++ b/codes/go/pkg/tree_node.go @@ -22,8 +22,8 @@ func NewTreeNode(v int) *TreeNode { } } -// ArrayToTree Generate a binary tree with an array -func ArrayToTree(arr []int) *TreeNode { +// ArrToTree Generate a binary tree given an array +func ArrToTree(arr []int) *TreeNode { if len(arr) <= 0 { return nil } @@ -31,19 +31,19 @@ func ArrayToTree(arr []int) *TreeNode { // Let container.list as queue queue := list.New() queue.PushBack(root) - i := 1 + i := 0 for queue.Len() > 0 { // poll node := queue.Remove(queue.Front()).(*TreeNode) + i++ if i < len(arr) { node.Left = NewTreeNode(arr[i]) queue.PushBack(node.Left) - i++ } + i++ if i < len(arr) { node.Right = NewTreeNode(arr[i]) queue.PushBack(node.Right) - i++ } } return root diff --git a/codes/go/pkg/tree_node_test.go b/codes/go/pkg/tree_node_test.go index b4c8e0773..bb1885ee1 100644 --- a/codes/go/pkg/tree_node_test.go +++ b/codes/go/pkg/tree_node_test.go @@ -11,7 +11,7 @@ import ( func TestTreeNode(t *testing.T) { arr := []int{2, 3, 5, 6, 7} - node := ArrayToTree(arr) + node := ArrToTree(arr) // print tree PrintTree(node) diff --git a/codes/java/chapter_heap/my_heap.java b/codes/java/chapter_heap/my_heap.java new file mode 100644 index 000000000..da2dffc0a --- /dev/null +++ b/codes/java/chapter_heap/my_heap.java @@ -0,0 +1,115 @@ +/** + * File: my_heap.java + * Created Time: 2023-01-07 + * Author: Krahets (krahets@163.com) + */ + +package chapter_heap; + +import include.*; +import java.util.*; + +class MaxHeap { + private List heap; + + public MaxHeap() { + heap = new ArrayList<>(); + } + + public MaxHeap(List nums) { + // 将元素拷贝至堆中 + heap = new ArrayList<>(nums); + // 堆化除叶结点外的其他所有结点 + for (int i = parent(size() - 1); i >= 0; i--) { + heapify(i); + } + } + + /* 获取左子结点 */ + private int left(int i) { + return 2 * i + 1; + } + + /* 获取右子结点 */ + private int right(int i) { + return 2 * i + 2; + } + + /* 获取父结点 */ + private int parent(int i) { + return (i - 1) / 2; + } + + /* 交换元素 */ + private void swap(int i, int j) { + int tmp = heap.get(i); + heap.set(i, j); + heap.set(j, tmp); + } + + public int size() { + return heap.size(); + } + + public boolean isEmpty() { + return size() == 0; + } + + /* 获取堆顶元素 */ + public int peek() { + return heap.get(0); + } + + /* 元素入堆 */ + public void push(int val) { + heap.add(val); + + // 从底至顶堆化 + int i = size(); + while (true) { + int p = parent(i); + if (p < 0 || heap.get(i) > heap.get(p)) + break; + swap(i, p); + i = p; + } + } + + /* 元素出堆 */ + public int poll() { + // 判空处理 + if (isEmpty()) + throw new EmptyStackException(); + // 交换根结点与右下角(即最后一个)结点 + swap(0, size() - 1); + // 删除结点 + int val = heap.remove(size() - 1); + // 从顶至底堆化 + heapify(0); + // 返回堆顶元素 + return val; + } + + /* 从结点 i 开始,从顶至底堆化 */ + private void heapify(int i) { + while (true) { + // 判断结点 i, l, r 中的最大结点,记为 ma ; + int l = left(i), r = right(i), ma = i; + if (heap.get(l) > heap.get(ma)) ma = l; + if (heap.get(r) > heap.get(ma)) ma = r; + // 若结点 i 最大,则无需继续堆化,跳出 + if (ma == i) break; + // 交换结点 i 与结点 max + swap(i, ma); + // 循环向下堆化 + i = ma; + } + } +} + + +public class my_heap { + public static void main(String[] args) { + + } +} diff --git a/codes/java/chapter_tree/binary_tree_bfs.java b/codes/java/chapter_tree/binary_tree_bfs.java index c000eacea..450311d08 100644 --- a/codes/java/chapter_tree/binary_tree_bfs.java +++ b/codes/java/chapter_tree/binary_tree_bfs.java @@ -30,8 +30,7 @@ public class binary_tree_bfs { public static void main(String[] args) { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode root = TreeNode.arrToTree(new Integer[] { - 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null }); + TreeNode root = TreeNode.arrToTree(new Integer[] { 1, 2, 3, 4, 5, 6, 7 }); System.out.println("\n初始化二叉树\n"); PrintUtil.printTree(root); diff --git a/codes/java/chapter_tree/binary_tree_dfs.java b/codes/java/chapter_tree/binary_tree_dfs.java index 1d3026dfb..d1ef063b0 100644 --- a/codes/java/chapter_tree/binary_tree_dfs.java +++ b/codes/java/chapter_tree/binary_tree_dfs.java @@ -43,8 +43,7 @@ public class binary_tree_dfs { public static void main(String[] args) { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 - TreeNode root = TreeNode.arrToTree(new Integer[] { - 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null}); + TreeNode root = TreeNode.arrToTree(new Integer[] { 1, null, 3, 4, 5 }); System.out.println("\n初始化二叉树\n"); PrintUtil.printTree(root); diff --git a/codes/java/include/PrintUtil.java b/codes/java/include/PrintUtil.java index f21bc17c9..b2593ac1f 100755 --- a/codes/java/include/PrintUtil.java +++ b/codes/java/include/PrintUtil.java @@ -8,6 +8,7 @@ package include; import java.util.*; + class Trunk { Trunk prev; String str; @@ -103,4 +104,11 @@ public class PrintUtil { System.out.println(kv.getKey() + " -> " + kv.getValue()); } } + + public static void printHeap(PriorityQueue queue) { + Integer[] nums = (Integer[])queue.toArray(); + TreeNode root = TreeNode.arrToTree(nums); + + printTree(root); + } } diff --git a/codes/java/include/TreeNode.java b/codes/java/include/TreeNode.java index b98252665..11d457a10 100644 --- a/codes/java/include/TreeNode.java +++ b/codes/java/include/TreeNode.java @@ -22,7 +22,7 @@ public class TreeNode { } /** - * Generate a binary tree with an array + * Generate a binary tree given an array * @param arr * @return */ @@ -32,19 +32,19 @@ public class TreeNode { TreeNode root = new TreeNode(arr[0]); Queue queue = new LinkedList<>() {{ add(root); }}; - int i = 1; + int i = 0; while(!queue.isEmpty()) { TreeNode node = queue.poll(); + if (++i >= arr.length) break; if(arr[i] != null) { node.left = new TreeNode(arr[i]); queue.add(node.left); } - i++; + if (++i >= arr.length) break; if(arr[i] != null) { node.right = new TreeNode(arr[i]); queue.add(node.right); } - i++; } return root; } @@ -71,20 +71,4 @@ public class TreeNode { } return list; } - - /** - * Get a tree node with specific value in a binary tree - * @param root - * @param val - * @return - */ - public static TreeNode getTreeNode(TreeNode root, int val) { - if (root == null) - return null; - if (root.val == val) - return root; - TreeNode left = getTreeNode(root.left, val); - TreeNode right = getTreeNode(root.right, val); - return left != null ? left : right; - } } diff --git a/codes/javascript/chapter_tree/binary_tree_bfs.js b/codes/javascript/chapter_tree/binary_tree_bfs.js index b52f52820..21daaa8dc 100644 --- a/codes/javascript/chapter_tree/binary_tree_bfs.js +++ b/codes/javascript/chapter_tree/binary_tree_bfs.js @@ -28,10 +28,10 @@ function hierOrder(root) { /* Driver Code */ /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 -var root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +var root = arrToTree([1, 2, 3, 4, 5, 6, 7]); console.log("\n初始化二叉树\n"); printTree(root); /* 层序遍历 */ let list = hierOrder(root); -console.log("\n层序遍历的结点打印序列 = " + list); \ No newline at end of file +console.log("\n层序遍历的结点打印序列 = " + list); diff --git a/codes/javascript/chapter_tree/binary_tree_dfs.js b/codes/javascript/chapter_tree/binary_tree_dfs.js index 51e557336..d23b69b6d 100644 --- a/codes/javascript/chapter_tree/binary_tree_dfs.js +++ b/codes/javascript/chapter_tree/binary_tree_dfs.js @@ -40,7 +40,7 @@ function postOrder(root) { /* Driver Code */ /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 -var root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +var root = arrToTree([1, 2, 3, 4, 5, 6, 7]); console.log("\n初始化二叉树\n"); printTree(root); @@ -58,4 +58,3 @@ console.log("\n中序遍历的结点打印序列 = " + list); list.length = 0; postOrder(root); console.log("\n后序遍历的结点打印序列 = " + list); - diff --git a/codes/javascript/include/TreeNode.js b/codes/javascript/include/TreeNode.js index 6add12f0c..ce6d667bf 100644 --- a/codes/javascript/include/TreeNode.js +++ b/codes/javascript/include/TreeNode.js @@ -14,7 +14,7 @@ function TreeNode(val, left, right) { } /** -* Generate a binary tree with an array +* Generate a binary tree given an array * @param arr * @return */ @@ -24,20 +24,21 @@ function arrToTree(arr) { let root = new TreeNode(arr[0]); let queue = [root] - let i = 1; - while(queue.length) { + let i = 0; + while (queue.length) { let node = queue.shift(); - if(arr[i] !== null) { + if (++i >= arr.length) break; + if (arr[i] !== null) { node.left = new TreeNode(arr[i]); queue.push(node.left); } - i++; - if(arr[i] !== null) { + if (++i >= arr.length) break; + if (arr[i] !== null) { node.right = new TreeNode(arr[i]); queue.push(node.right); } - i++; } + return root; } diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index db52d57bd..7633b6288 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -138,7 +138,7 @@ class BinarySearchTree: """ Driver Code """ if __name__ == "__main__": # 初始化二叉搜索树 - nums = list(range(1, 16)) + nums = list(range(1, 16)) # [1, 2, ..., 15] bst = BinarySearchTree(nums=nums) print("\n初始化的二叉树为\n") print_tree(bst.root) diff --git a/codes/python/chapter_tree/binary_tree.py b/codes/python/chapter_tree/binary_tree.py index d99026352..e00eeb4e5 100644 --- a/codes/python/chapter_tree/binary_tree.py +++ b/codes/python/chapter_tree/binary_tree.py @@ -36,5 +36,5 @@ if __name__ == "__main__": print_tree(n1) # 删除结点 n1.left = n2 - print("\n删除结点 P 后\n"); + print("\n删除结点 P 后\n") print_tree(n1) diff --git a/codes/python/chapter_tree/binary_tree_bfs.py b/codes/python/chapter_tree/binary_tree_bfs.py index 0320a08dd..225a8bd6e 100644 --- a/codes/python/chapter_tree/binary_tree_bfs.py +++ b/codes/python/chapter_tree/binary_tree_bfs.py @@ -32,7 +32,7 @@ def hier_order(root: TreeNode): if __name__ == "__main__": # 初始化二叉树 # 这里借助了一个从数组直接生成二叉树的函数 - root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7, None, None, None, None, None, None, None, None]) + root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7]) print("\n初始化二叉树\n") print_tree(root) diff --git a/codes/python/chapter_tree/binary_tree_dfs.py b/codes/python/chapter_tree/binary_tree_dfs.py index 11ee8339c..a1d46e697 100644 --- a/codes/python/chapter_tree/binary_tree_dfs.py +++ b/codes/python/chapter_tree/binary_tree_dfs.py @@ -45,7 +45,7 @@ def post_order(root: typing.Optional[TreeNode]): if __name__ == "__main__": # 初始化二叉树 # 这里借助了一个从数组直接生成二叉树的函数 - root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7, None, None, None, None, None, None, None, None]) + root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7]) print("\n初始化二叉树\n") print_tree(root) diff --git a/codes/python/include/binary_tree.py b/codes/python/include/binary_tree.py index 670fd18ce..9d612a7e2 100644 --- a/codes/python/include/binary_tree.py +++ b/codes/python/include/binary_tree.py @@ -26,39 +26,30 @@ class TreeNode: def list_to_tree(arr): """Generate a binary tree with a list - - Args: - arr ([type]): [description] - - Returns: - [type]: [description] """ if not arr: return None - i = 1 - root = TreeNode(int(arr[0])) - queue = collections.deque() - queue.append(root) + + i = 0 + root = TreeNode(arr[0]) + queue = collections.deque([root]) while queue: node = queue.popleft() + i += 1 + if i >= len(arr): break if arr[i] != None: - node.left = TreeNode(int(arr[i])) + node.left = TreeNode(arr[i]) queue.append(node.left) i += 1 + if i >= len(arr): break if arr[i] != None: - node.right = TreeNode(int(arr[i])) + node.right = TreeNode(arr[i]) queue.append(node.right) - i += 1 + return root def tree_to_list(root): """Serialize a tree into an array - - Args: - root ([type]): [description] - - Returns: - [type]: [description] """ if not root: return [] queue = collections.deque() @@ -75,13 +66,6 @@ def tree_to_list(root): def get_tree_node(root, val): """Get a tree node with specific value in a binary tree - - Args: - root ([type]): [description] - val ([type]): [description] - - Returns: - [type]: [description] """ if not root: return diff --git a/codes/typescript/chapter_tree/binary_tree_bfs.ts b/codes/typescript/chapter_tree/binary_tree_bfs.ts index 1e57ef62d..7ec4a2a5c 100644 --- a/codes/typescript/chapter_tree/binary_tree_bfs.ts +++ b/codes/typescript/chapter_tree/binary_tree_bfs.ts @@ -30,7 +30,7 @@ function hierOrder(root: TreeNode | null): number[] { /* Driver Code */ /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 -var root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +var root = arrToTree([1, 2, 3, 4, 5, 6, 7]); console.log('\n初始化二叉树\n'); printTree(root); diff --git a/codes/typescript/chapter_tree/binary_tree_dfs.ts b/codes/typescript/chapter_tree/binary_tree_dfs.ts index d9e982df1..a61855af8 100644 --- a/codes/typescript/chapter_tree/binary_tree_dfs.ts +++ b/codes/typescript/chapter_tree/binary_tree_dfs.ts @@ -47,7 +47,7 @@ function postOrder(root: TreeNode | null): void { /* Driver Code */ /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 -const root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +const root = arrToTree([1, 2, 3, 4, 5, 6, 7]); console.log('\n初始化二叉树\n'); printTree(root); diff --git a/codes/typescript/module/TreeNode.ts b/codes/typescript/module/TreeNode.ts index 5a886763e..0e3425006 100644 --- a/codes/typescript/module/TreeNode.ts +++ b/codes/typescript/module/TreeNode.ts @@ -20,7 +20,7 @@ class TreeNode { } /** - * Generate a binary tree with an array + * Generate a binary tree given an array * @param arr * @return */ @@ -31,19 +31,19 @@ function arrToTree(arr: (number | null)[]): TreeNode | null { const root = new TreeNode(arr[0] as number); const queue = [root]; - let i = 1; + let i = 0; while (queue.length) { let node = queue.shift() as TreeNode; + if (++i >= arr.length) break; if (arr[i] !== null) { node.left = new TreeNode(arr[i] as number); queue.push(node.left); } - i++; + if (++i >= arr.length) break; if (arr[i] !== null) { node.right = new TreeNode(arr[i] as number); queue.push(node.right); } - i++; } return root; } diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index def4cde5b..b0151622f 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -2,26 +2,48 @@ 「堆 Heap」是一种特殊的树状数据结构,并且是一颗「完全二叉树」。堆主要分为两种: -- 「大顶堆 Max Heap」,任意父结点的值 > 其子结点的值,因此根结点的值最大; -- 「小顶堆 Min Heap」,任意父结点的值 < 其子结点的值,因此根结点的值最小; +- 「大顶堆 Max Heap」,任意结点的值 $\geq$ 其子结点的值,因此根结点的值最大; +- 「小顶堆 Min Heap」,任意结点的值 $\leq$ 其子结点的值,因此根结点的值最小; (图) !!! tip "" - 大顶堆和小顶堆的定义、性质、操作本质上是一样的。区别只是大顶堆在求最大值,小顶堆在求最小值。在下文中,我们将统一用「大顶堆」来举例,「小顶堆」的用法与实现可以简单地将所有 $>$ ($<$) 替换为 $<$ ($>$) 即可。 + 大顶堆和小顶堆的定义、性质、操作本质上是相同的,区别只是大顶堆在求最大值,小顶堆在求最小值。 ## 堆常用操作 -堆的初始化。 +值得说明的是,多数编程语言提供的是「优先队列 Priority Queue」,其是一种抽象数据结构,**定义为具有出队优先级的队列**。 -获取堆顶元素。 +而恰好,堆的定义与优先队列的操作逻辑完全吻合,大顶堆就是一个元素从大到小出队的优先队列。从使用角度看,我们可以将「优先队列」和「堆」理解为等价的数据结构,下文将统一使用 “堆” 这个名称。 -添加与删除元素。 +堆的常用操作见下表(方法命名以 Java 为例)。 + +

Table. 堆的常用操作

+ +
+ +| 方法 | 描述 | +| --------- | -------------------------------------------- | +| add() | 元素入堆 | +| poll() | 堆顶元素出堆 | +| peek() | 访问堆顶元素(大 / 小顶堆分别为最大 / 小值) | +| size() | 获取堆的元素数量 | +| isEmpty() | 判断堆是否为空 | + +
+ +```java + +``` ## 堆的实现 -在二叉树章节中,我们讲过二叉树的数组表示方法,并且提到完全二叉树非常适合用数组来表示,因此我们一般使用「数组」来存储「堆」。 +!!! tip + + 下文使用「大顶堆」来举例,「小顶堆」的用法与实现可以简单地将所有 $>$ ($<$) 替换为 $<$ ($>$) 即可。 + +我们一般使用「数组」来存储「堆」,这是因为完全二叉树非常适合用数组来表示(在二叉树章节有详细解释)。 diff --git a/docs/chapter_tree/binary_tree.assets/binary_tree_add_remove.png b/docs/chapter_tree/binary_tree.assets/binary_tree_add_remove.png index b7922fcb3..d95c48f07 100644 Binary files a/docs/chapter_tree/binary_tree.assets/binary_tree_add_remove.png and b/docs/chapter_tree/binary_tree.assets/binary_tree_add_remove.png differ