diff --git a/codes/c/chapter_tree/binary_search_tree.c b/codes/c/chapter_tree/binary_search_tree.c index d72779e3b..707a27c5b 100644 --- a/codes/c/chapter_tree/binary_search_tree.c +++ b/codes/c/chapter_tree/binary_search_tree.c @@ -70,9 +70,11 @@ TreeNode *search(binarySearchTree *bst, int num) { /* 插入节点 */ void insert(binarySearchTree *bst, int num) { - // 若树为空,直接提前返回 - if (bst->root == NULL) + // 若树为空,则初始化根节点 + if (bst->root == NULL) { + bst->root = newTreeNode(num); return; + } TreeNode *cur = bst->root, *pre = NULL; // 循环查找,越过叶节点后跳出 while (cur != NULL) { diff --git a/codes/cpp/chapter_tree/binary_search_tree.cpp b/codes/cpp/chapter_tree/binary_search_tree.cpp index 195a1a1ce..9cd99f817 100644 --- a/codes/cpp/chapter_tree/binary_search_tree.cpp +++ b/codes/cpp/chapter_tree/binary_search_tree.cpp @@ -12,11 +12,13 @@ class BinarySearchTree { TreeNode *root; public: - BinarySearchTree(vector nums) { - sort(nums.begin(), nums.end()); // 排序数组 - root = buildTree(nums, 0, nums.size() - 1); // 构建二叉搜索树 + /* 构造方法 */ + BinarySearchTree() { + // 初始化空树 + root = nullptr; } + /* 析构方法 */ ~BinarySearchTree() { freeMemoryTree(root); } @@ -26,19 +28,6 @@ class BinarySearchTree { return root; } - /* 构建二叉搜索树 */ - TreeNode *buildTree(vector nums, int i, int j) { - if (i > j) - return nullptr; - // 将数组中间节点作为根节点 - int mid = (i + j) / 2; - TreeNode *root = new TreeNode(nums[mid]); - // 递归建立左子树和右子树 - root->left = buildTree(nums, i, mid - 1); - root->right = buildTree(nums, mid + 1, j); - return root; - } - /* 查找节点 */ TreeNode *search(int num) { TreeNode *cur = root; @@ -60,9 +49,11 @@ class BinarySearchTree { /* 插入节点 */ void insert(int num) { - // 若树为空,直接提前返回 - if (root == nullptr) + // 若树为空,则初始化根节点 + if (root == nullptr) { + root = new TreeNode(num); return; + } TreeNode *cur = root, *pre = nullptr; // 循环查找,越过叶节点后跳出 while (cur != nullptr) { @@ -143,8 +134,12 @@ class BinarySearchTree { /* Driver Code */ int main() { /* 初始化二叉搜索树 */ - vector nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - BinarySearchTree *bst = new BinarySearchTree(nums); + BinarySearchTree *bst = new BinarySearchTree(); + // 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + vector nums = {8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15}; + for (int num : nums) { + bst->insert(num); + } cout << endl << "初始化的二叉树为\n" << endl; printTree(bst->getRoot()); diff --git a/codes/csharp/chapter_tree/binary_search_tree.cs b/codes/csharp/chapter_tree/binary_search_tree.cs index 88bd9fe65..07c078534 100644 --- a/codes/csharp/chapter_tree/binary_search_tree.cs +++ b/codes/csharp/chapter_tree/binary_search_tree.cs @@ -54,9 +54,11 @@ class BinarySearchTree { /* 插入节点 */ public void insert(int num) { - // 若树为空,直接提前返回 - if (root == null) + // 若树为空,则初始化根节点 + if (root == null) { + root = new TreeNode(num); return; + } TreeNode? cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { diff --git a/codes/dart/chapter_tree/binary_search_tree.dart b/codes/dart/chapter_tree/binary_search_tree.dart index 2443ba115..05c5377d8 100644 --- a/codes/dart/chapter_tree/binary_search_tree.dart +++ b/codes/dart/chapter_tree/binary_search_tree.dart @@ -56,8 +56,11 @@ class BinarySearchTree { /* 插入节点 */ void insert(int num) { - // 若树为空,直接提前返回 - if (_root == null) return; + // 若树为空,则初始化根节点 + if (_root == null) { + _root = TreeNode(num); + return; + } TreeNode? cur = _root; TreeNode? pre = null; // 循环查找,越过叶节点后跳出 diff --git a/codes/go/chapter_tree/binary_search_tree.go b/codes/go/chapter_tree/binary_search_tree.go index 1a0829883..60471ca20 100644 --- a/codes/go/chapter_tree/binary_search_tree.go +++ b/codes/go/chapter_tree/binary_search_tree.go @@ -5,8 +5,6 @@ package chapter_tree import ( - "sort" - . "github.com/krahets/hello-algo/pkg" ) @@ -14,29 +12,13 @@ type binarySearchTree struct { root *TreeNode } -func newBinarySearchTree(nums []int) *binarySearchTree { - // 排序数组 - sort.Ints(nums) - // 构建二叉搜索树 +func newBinarySearchTree() *binarySearchTree { bst := &binarySearchTree{} - bst.root = bst.buildTree(nums, 0, len(nums)-1) + // 初始化空树 + bst.root = nil return bst } -/* 构建二叉搜索树 */ -func (bst *binarySearchTree) buildTree(nums []int, left, right int) *TreeNode { - if left > right { - return nil - } - // 将数组中间节点作为根节点 - middle := left + (right-left)>>1 - root := NewTreeNode(nums[middle]) - // 递归构建左子树和右子树 - root.Left = bst.buildTree(nums, left, middle-1) - root.Right = bst.buildTree(nums, middle+1, right) - return root -} - /* 获取根节点 */ func (bst *binarySearchTree) getRoot() *TreeNode { return bst.root @@ -65,8 +47,9 @@ func (bst *binarySearchTree) search(num int) *TreeNode { /* 插入节点 */ func (bst *binarySearchTree) insert(num int) { cur := bst.root - // 若树为空,直接提前返回 + // 若树为空,则初始化根节点 if cur == nil { + bst.root = NewTreeNode(num) return } // 待插入节点之前的节点位置 diff --git a/codes/go/chapter_tree/binary_search_tree_test.go b/codes/go/chapter_tree/binary_search_tree_test.go index 2733adb1a..65b72840f 100644 --- a/codes/go/chapter_tree/binary_search_tree_test.go +++ b/codes/go/chapter_tree/binary_search_tree_test.go @@ -10,8 +10,12 @@ import ( ) func TestBinarySearchTree(t *testing.T) { - nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} - bst := newBinarySearchTree(nums) + bst := newBinarySearchTree() + nums := []int{8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15} + // 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + for _, num := range nums { + bst.insert(num) + } fmt.Println("\n初始化的二叉树为:") bst.print() diff --git a/codes/java/chapter_tree/binary_search_tree.java b/codes/java/chapter_tree/binary_search_tree.java index 2abc445e1..506966652 100644 --- a/codes/java/chapter_tree/binary_search_tree.java +++ b/codes/java/chapter_tree/binary_search_tree.java @@ -6,16 +6,16 @@ package chapter_tree; -import java.util.*; import utils.*; /* 二叉搜索树 */ class BinarySearchTree { private TreeNode root; - public BinarySearchTree(int[] nums) { - Arrays.sort(nums); // 排序数组 - root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树 + /* 构造方法 */ + public BinarySearchTree() { + // 初始化空树 + root = null; } /* 获取二叉树根节点 */ @@ -23,19 +23,6 @@ class BinarySearchTree { return root; } - /* 构建二叉搜索树 */ - public TreeNode buildTree(int[] nums, int i, int j) { - if (i > j) - return null; - // 将数组中间节点作为根节点 - int mid = (i + j) / 2; - TreeNode root = new TreeNode(nums[mid]); - // 递归建立左子树和右子树 - root.left = buildTree(nums, i, mid - 1); - root.right = buildTree(nums, mid + 1, j); - return root; - } - /* 查找节点 */ public TreeNode search(int num) { TreeNode cur = root; @@ -57,9 +44,11 @@ class BinarySearchTree { /* 插入节点 */ public void insert(int num) { - // 若树为空,直接提前返回 - if (root == null) + // 若树为空,则初始化根节点 + if (root == null) { + root = new TreeNode(num); return; + } TreeNode cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { @@ -137,8 +126,12 @@ class BinarySearchTree { public class binary_search_tree { public static void main(String[] args) { /* 初始化二叉搜索树 */ - int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; - BinarySearchTree bst = new BinarySearchTree(nums); + BinarySearchTree bst = new BinarySearchTree(); + // 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + int[] nums = { 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 }; + for (int num : nums) { + bst.insert(num); + } System.out.println("\n初始化的二叉树为\n"); PrintUtil.printTree(bst.getRoot()); diff --git a/codes/javascript/chapter_tree/avl_tree.js b/codes/javascript/chapter_tree/avl_tree.js index 6cb32b4e8..eb33933f1 100644 --- a/codes/javascript/chapter_tree/avl_tree.js +++ b/codes/javascript/chapter_tree/avl_tree.js @@ -9,7 +9,7 @@ const { printTree } = require('../modules/PrintUtil'); /* AVL 树*/ class AVLTree { - /*构造方法*/ + /* 构造方法 */ constructor() { this.root = null; //根节点 } diff --git a/codes/javascript/chapter_tree/binary_search_tree.js b/codes/javascript/chapter_tree/binary_search_tree.js index 601770d15..38a917e16 100644 --- a/codes/javascript/chapter_tree/binary_search_tree.js +++ b/codes/javascript/chapter_tree/binary_search_tree.js @@ -8,138 +8,132 @@ const { TreeNode } = require('../modules/TreeNode'); const { printTree } = require('../modules/PrintUtil'); /* 二叉搜索树 */ -let root; - -function BinarySearchTree(nums) { - nums.sort((a, b) => { - return a - b; - }); // 排序数组 - root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树 -} - -/* 获取二叉树根节点 */ -function getRoot() { - return root; -} - -/* 构建二叉搜索树 */ -function buildTree(nums, i, j) { - if (i > j) return null; - // 将数组中间节点作为根节点 - let mid = Math.floor((i + j) / 2); - let root = new TreeNode(nums[mid]); - // 递归建立左子树和右子树 - root.left = buildTree(nums, i, mid - 1); - root.right = buildTree(nums, mid + 1, j); - return root; -} - -/* 查找节点 */ -function search(num) { - let cur = root; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - // 目标节点在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 目标节点在 cur 的左子树中 - else if (cur.val > num) cur = cur.left; - // 找到目标节点,跳出循环 - else break; +class BinarySearchTree { + /* 构造方法 */ + constructor() { + // 初始化空树 + this.root = null; } - // 返回目标节点 - return cur; -} -/* 插入节点 */ -function insert(num) { - // 若树为空,直接提前返回 - if (root === null) return; - let cur = root, - pre = null; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - // 找到重复节点,直接返回 - if (cur.val === num) return; - pre = cur; - // 插入位置在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 插入位置在 cur 的左子树中 - else cur = cur.left; + /* 获取二叉树根节点 */ + getRoot() { + return this.root; } - // 插入节点 - let node = new TreeNode(num); - if (pre.val < num) pre.right = node; - else pre.left = node; -} -/* 删除节点 */ -function remove(num) { - // 若树为空,直接提前返回 - if (root === null) return; - let cur = root, - pre = null; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - // 找到待删除节点,跳出循环 - if (cur.val === num) break; - pre = cur; - // 待删除节点在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 待删除节点在 cur 的左子树中 - else cur = cur.left; + /* 查找节点 */ + search(num) { + let cur = this.root; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 目标节点在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 目标节点在 cur 的左子树中 + else if (cur.val > num) cur = cur.left; + // 找到目标节点,跳出循环 + else break; + } + // 返回目标节点 + return cur; } - // 若无待删除节点,则直接返回 - if (cur === null) return; - // 子节点数量 = 0 or 1 - if (cur.left === null || cur.right === null) { - // 当子节点数量 = 0 / 1 时, child = null / 该子节点 - let child = cur.left !== null ? cur.left : cur.right; - // 删除节点 cur - if (cur != root) { - if (pre.left === cur) pre.left = child; - else pre.right = child; - } else { - // 若删除节点为根节点,则重新指定根节点 - root = child; + + /* 插入节点 */ + insert(num) { + // 若树为空,则初始化根节点 + if (this.root === null) { + this.root = new TreeNode(num); + return; + } + let cur = this.root, + pre = null; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 找到重复节点,直接返回 + if (cur.val === num) return; + pre = cur; + // 插入位置在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 插入位置在 cur 的左子树中 + else cur = cur.left; } + // 插入节点 + let node = new TreeNode(num); + if (pre.val < num) pre.right = node; + else pre.left = node; } - // 子节点数量 = 2 - else { - // 获取中序遍历中 cur 的下一个节点 - let tmp = cur.right; - while (tmp.left !== null) { - tmp = tmp.left; + + /* 删除节点 */ + remove(num) { + // 若树为空,直接提前返回 + if (this.root === null) return; + let cur = this.root, + pre = null; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 找到待删除节点,跳出循环 + if (cur.val === num) break; + pre = cur; + // 待删除节点在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 待删除节点在 cur 的左子树中 + else cur = cur.left; + } + // 若无待删除节点,则直接返回 + if (cur === null) return; + // 子节点数量 = 0 or 1 + if (cur.left === null || cur.right === null) { + // 当子节点数量 = 0 / 1 时, child = null / 该子节点 + let child = cur.left !== null ? cur.left : cur.right; + // 删除节点 cur + if (cur !== this.root) { + if (pre.left === cur) pre.left = child; + else pre.right = child; + } else { + // 若删除节点为根节点,则重新指定根节点 + this.root = child; + } + } + // 子节点数量 = 2 + else { + // 获取中序遍历中 cur 的下一个节点 + let tmp = cur.right; + while (tmp.left !== null) { + tmp = tmp.left; + } + // 递归删除节点 tmp + this.remove(tmp.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - // 递归删除节点 tmp - remove(tmp.val); - // 用 tmp 覆盖 cur - cur.val = tmp.val; } } /* Driver Code */ /* 初始化二叉搜索树 */ -const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; -BinarySearchTree(nums); +const bst = new BinarySearchTree(); +// 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 +const nums = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15]; +for (const num of nums) { + bst.insert(num); +} console.log('\n初始化的二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); /* 查找节点 */ -let node = search(7); +let node = bst.search(7); console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + node.val); /* 插入节点 */ -insert(16); +bst.insert(16); console.log('\n插入节点 16 后,二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); /* 删除节点 */ -remove(1); +bst.remove(1); console.log('\n删除节点 1 后,二叉树为\n'); -printTree(getRoot()); -remove(2); +printTree(bst.getRoot()); +bst.remove(2); console.log('\n删除节点 2 后,二叉树为\n'); -printTree(getRoot()); -remove(4); +printTree(bst.getRoot()); +bst.remove(4); console.log('\n删除节点 4 后,二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index c773d7003..4ed0e498b 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -13,33 +13,18 @@ from modules import * class BinarySearchTree: """二叉搜索树""" - def __init__(self, nums: list[int]): + def __init__(self): """构造方法""" - nums.sort() - self.root = self.build_tree(nums, 0, len(nums) - 1) - - def build_tree( - self, nums: list[int], start_index: int, end_index: int - ) -> TreeNode | None: - """构建二叉搜索树""" - if start_index > end_index: - return None - - # 将数组中间节点作为根节点 - mid = (start_index + end_index) // 2 - root = TreeNode(nums[mid]) - # 递归建立左子树和右子树 - root.left = self.build_tree( - nums=nums, start_index=start_index, end_index=mid - 1 - ) - root.right = self.build_tree( - nums=nums, start_index=mid + 1, end_index=end_index - ) - return root + # 初始化空树 + self.__root = None + + def get_root(self) -> TreeNode | None: + """获取二叉树根节点""" + return self.__root def search(self, num: int) -> TreeNode | None: """查找节点""" - cur: TreeNode | None = self.root + cur = self.__root # 循环查找,越过叶节点后跳出 while cur is not None: # 目标节点在 cur 的右子树中 @@ -55,12 +40,12 @@ class BinarySearchTree: def insert(self, num: int): """插入节点""" - # 若树为空,直接提前返回 - if self.root is None: + # 若树为空,则初始化根节点 + if self.__root is None: + self.__root = TreeNode(num) return - # 循环查找,越过叶节点后跳出 - cur, pre = self.root, None + cur, pre = self.__root, None while cur is not None: # 找到重复节点,直接返回 if cur.val == num: @@ -72,7 +57,6 @@ class BinarySearchTree: # 插入位置在 cur 的左子树中 else: cur = cur.left - # 插入节点 node = TreeNode(num) if pre.val < num: @@ -83,11 +67,10 @@ class BinarySearchTree: def remove(self, num: int): """删除节点""" # 若树为空,直接提前返回 - if self.root is None: + if self.__root is None: return - # 循环查找,越过叶节点后跳出 - cur, pre = self.root, None + cur, pre = self.__root, None while cur is not None: # 找到待删除节点,跳出循环 if cur.val == num: @@ -108,14 +91,14 @@ class BinarySearchTree: # 当子节点数量 = 0 / 1 时, child = null / 该子节点 child = cur.left or cur.right # 删除节点 cur - if cur != self.root: + if cur != self.__root: if pre.left == cur: pre.left = child else: pre.right = child else: # 若删除节点为根节点,则重新指定根节点 - self.root = child + self.__root = child # 子节点数量 = 2 else: # 获取中序遍历中 cur 的下一个节点 @@ -131,10 +114,13 @@ class BinarySearchTree: """Driver Code""" if __name__ == "__main__": # 初始化二叉搜索树 - nums = list(range(1, 16)) # [1, 2, ..., 15] - bst = BinarySearchTree(nums=nums) + bst = BinarySearchTree() + nums = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15] + # 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + for num in nums: + bst.insert(num) print("\n初始化的二叉树为\n") - print_tree(bst.root) + print_tree(bst.get_root()) # 查找节点 node = bst.search(7) @@ -143,17 +129,17 @@ if __name__ == "__main__": # 插入节点 bst.insert(16) print("\n插入节点 16 后,二叉树为\n") - print_tree(bst.root) + print_tree(bst.get_root()) # 删除节点 bst.remove(1) print("\n删除节点 1 后,二叉树为\n") - print_tree(bst.root) + print_tree(bst.get_root()) bst.remove(2) print("\n删除节点 2 后,二叉树为\n") - print_tree(bst.root) + print_tree(bst.get_root()) bst.remove(4) print("\n删除节点 4 后,二叉树为\n") - print_tree(bst.root) + print_tree(bst.get_root()) diff --git a/codes/rust/chapter_tree/binary_search_tree.rs b/codes/rust/chapter_tree/binary_search_tree.rs index 6e49fb4db..1ed22a3e0 100644 --- a/codes/rust/chapter_tree/binary_search_tree.rs +++ b/codes/rust/chapter_tree/binary_search_tree.rs @@ -74,8 +74,9 @@ impl BinarySearchTree { /* 插入节点 */ pub fn insert(&mut self, num: i32) { - // 若树为空,直接提前返回 + // 若树为空,则初始化根节点 if self.root.is_none() { + self.root = TreeNode::new(num); return; } let mut cur = self.root.clone(); diff --git a/codes/swift/chapter_tree/binary_search_tree.swift b/codes/swift/chapter_tree/binary_search_tree.swift index f9e6d1ba8..b84432e29 100644 --- a/codes/swift/chapter_tree/binary_search_tree.swift +++ b/codes/swift/chapter_tree/binary_search_tree.swift @@ -58,8 +58,9 @@ class BinarySearchTree { /* 插入节点 */ func insert(num: Int) { - // 若树为空,直接提前返回 + // 若树为空,则初始化根节点 if root == nil { + root = TreeNode(x: num) return } var cur = root diff --git a/codes/typescript/chapter_tree/binary_search_tree.ts b/codes/typescript/chapter_tree/binary_search_tree.ts index 8a08caa18..de8393095 100644 --- a/codes/typescript/chapter_tree/binary_search_tree.ts +++ b/codes/typescript/chapter_tree/binary_search_tree.ts @@ -53,8 +53,9 @@ function search(num: number): TreeNode | null { /* 插入节点 */ function insert(num: number): void { - // 若树为空,直接提前返回 + // 若树为空,则初始化根节点 if (root === null) { + root = new TreeNode(num); return; } let cur = root, diff --git a/codes/zig/chapter_tree/binary_search_tree.zig b/codes/zig/chapter_tree/binary_search_tree.zig index 7a35c125a..04a0c2696 100644 --- a/codes/zig/chapter_tree/binary_search_tree.zig +++ b/codes/zig/chapter_tree/binary_search_tree.zig @@ -70,8 +70,11 @@ pub fn BinarySearchTree(comptime T: type) type { // 插入节点 fn insert(self: *Self, num: T) !void { - // 若树为空,直接提前返回 - if (self.root == null) return; + // 若树为空,则初始化根节点 + if (self.root == null) { + self.root = try self.mem_allocator.create(inc.TreeNode(T)); + return; + } var cur = self.root; var pre: ?*inc.TreeNode(T) = null; // 循环查找,越过叶节点后跳出