mirror of
https://github.com/krahets/hello-algo.git
synced 2025-02-02 22:43:50 +08:00
Optimize arrToTree function
in java, cpp, py, go, js, ts.
This commit is contained in:
parent
c411969bd1
commit
dcc3b2e35b
4
.gitignore
vendored
4
.gitignore
vendored
@ -14,5 +14,5 @@ docs/overrides/
|
||||
# python files
|
||||
__pycache__
|
||||
|
||||
# iml
|
||||
hello-algo.iml
|
||||
# in-progress articles
|
||||
docs/chapter_heap
|
||||
|
@ -30,8 +30,7 @@ vector<int> hierOrder(TreeNode* root) {
|
||||
int main() {
|
||||
/* 初始化二叉树 */
|
||||
// 这里借助了一个从数组直接生成二叉树的函数
|
||||
TreeNode* root = vecToTree(vector<int>
|
||||
{ 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<int> { 1, 2, 3, 4, 5, 6, 7 });
|
||||
cout << endl << "初始化二叉树\n" << endl;
|
||||
PrintUtil::printTree(root);
|
||||
|
||||
|
@ -41,8 +41,7 @@ void postOrder(TreeNode* root) {
|
||||
int main() {
|
||||
/* 初始化二叉树 */
|
||||
// 这里借助了一个从数组直接生成二叉树的函数
|
||||
TreeNode* root = vecToTree(vector<int>
|
||||
{ 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<int> { 1, 2, 3, 4, 5, 6, 7 });
|
||||
cout << endl << "初始化二叉树\n" << endl;
|
||||
PrintUtil::printTree(root);
|
||||
|
||||
|
@ -27,23 +27,24 @@ struct TreeNode {
|
||||
* @return TreeNode*
|
||||
*/
|
||||
TreeNode *vecToTree(vector<int> list) {
|
||||
if (list.empty()) {
|
||||
if (list.empty())
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *root = new TreeNode(list[0]);
|
||||
queue<TreeNode *> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<TreeNode> queue = new Queue<TreeNode>();
|
||||
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;
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
115
codes/java/chapter_heap/my_heap.java
Normal file
115
codes/java/chapter_heap/my_heap.java
Normal file
@ -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<Integer> heap;
|
||||
|
||||
public MaxHeap() {
|
||||
heap = new ArrayList<>();
|
||||
}
|
||||
|
||||
public MaxHeap(List<Integer> 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) {
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<Integer> queue) {
|
||||
Integer[] nums = (Integer[])queue.toArray();
|
||||
TreeNode root = TreeNode.arrToTree(nums);
|
||||
|
||||
printTree(root);
|
||||
}
|
||||
}
|
||||
|
@ -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<TreeNode> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
console.log("\n层序遍历的结点打印序列 = " + list);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -36,5 +36,5 @@ if __name__ == "__main__":
|
||||
print_tree(n1)
|
||||
# 删除结点
|
||||
n1.left = n2
|
||||
print("\n删除结点 P 后\n");
|
||||
print("\n删除结点 P 后\n")
|
||||
print_tree(n1)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -2,26 +2,48 @@
|
||||
|
||||
「堆 Heap」是一种特殊的树状数据结构,并且是一颗「完全二叉树」。堆主要分为两种:
|
||||
|
||||
- 「大顶堆 Max Heap」,任意父结点的值 > 其子结点的值,因此根结点的值最大;
|
||||
- 「小顶堆 Min Heap」,任意父结点的值 < 其子结点的值,因此根结点的值最小;
|
||||
- 「大顶堆 Max Heap」,任意结点的值 $\geq$ 其子结点的值,因此根结点的值最大;
|
||||
- 「小顶堆 Min Heap」,任意结点的值 $\leq$ 其子结点的值,因此根结点的值最小;
|
||||
|
||||
(图)
|
||||
|
||||
!!! tip ""
|
||||
|
||||
大顶堆和小顶堆的定义、性质、操作本质上是一样的。区别只是大顶堆在求最大值,小顶堆在求最小值。在下文中,我们将统一用「大顶堆」来举例,「小顶堆」的用法与实现可以简单地将所有 $>$ ($<$) 替换为 $<$ ($>$) 即可。
|
||||
大顶堆和小顶堆的定义、性质、操作本质上是相同的,区别只是大顶堆在求最大值,小顶堆在求最小值。
|
||||
|
||||
## 堆常用操作
|
||||
|
||||
堆的初始化。
|
||||
值得说明的是,多数编程语言提供的是「优先队列 Priority Queue」,其是一种抽象数据结构,**定义为具有出队优先级的队列**。
|
||||
|
||||
获取堆顶元素。
|
||||
而恰好,堆的定义与优先队列的操作逻辑完全吻合,大顶堆就是一个元素从大到小出队的优先队列。从使用角度看,我们可以将「优先队列」和「堆」理解为等价的数据结构,下文将统一使用 “堆” 这个名称。
|
||||
|
||||
添加与删除元素。
|
||||
堆的常用操作见下表(方法命名以 Java 为例)。
|
||||
|
||||
<p align="center"> Table. 堆的常用操作 </p>
|
||||
|
||||
<div class="center-table" markdown>
|
||||
|
||||
| 方法 | 描述 |
|
||||
| --------- | -------------------------------------------- |
|
||||
| add() | 元素入堆 |
|
||||
| poll() | 堆顶元素出堆 |
|
||||
| peek() | 访问堆顶元素(大 / 小顶堆分别为最大 / 小值) |
|
||||
| size() | 获取堆的元素数量 |
|
||||
| isEmpty() | 判断堆是否为空 |
|
||||
|
||||
</div>
|
||||
|
||||
```java
|
||||
|
||||
```
|
||||
|
||||
## 堆的实现
|
||||
|
||||
在二叉树章节中,我们讲过二叉树的数组表示方法,并且提到完全二叉树非常适合用数组来表示,因此我们一般使用「数组」来存储「堆」。
|
||||
!!! tip
|
||||
|
||||
下文使用「大顶堆」来举例,「小顶堆」的用法与实现可以简单地将所有 $>$ ($<$) 替换为 $<$ ($>$) 即可。
|
||||
|
||||
我们一般使用「数组」来存储「堆」,这是因为完全二叉树非常适合用数组来表示(在二叉树章节有详细解释)。
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 78 KiB |
Loading…
Reference in New Issue
Block a user