Add C++ code for the chapter binary tree.
This commit is contained in:
		| @@ -6,3 +6,149 @@ | ||||
|  | ||||
| #include "../include/include.hpp" | ||||
|  | ||||
| /* 二叉搜索树 */ | ||||
| class BinarySearchTree { | ||||
| private: | ||||
|     TreeNode* root; | ||||
|  | ||||
| public: | ||||
|     BinarySearchTree(vector<int> nums) { | ||||
|         sort(nums.begin(), nums.end()); // 排序数组 | ||||
|         root = buildTree(nums, 0, nums.size() - 1);  // 构建二叉搜索树 | ||||
|     } | ||||
|  | ||||
|     /* 获取二叉树根结点 */ | ||||
|     TreeNode* getRoot() { | ||||
|         return root; | ||||
|     } | ||||
|  | ||||
|     /* 构建二叉搜索树 */ | ||||
|     TreeNode* buildTree(vector<int> 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; | ||||
|         // 循环查找,越过叶结点后跳出 | ||||
|         while (cur != nullptr) { | ||||
|             // 目标结点在 root 的右子树中 | ||||
|             if (cur->val < num) cur = cur->right; | ||||
|             // 目标结点在 root 的左子树中 | ||||
|             else if (cur->val > num) cur = cur->left; | ||||
|             // 找到目标结点,跳出循环 | ||||
|             else break; | ||||
|         } | ||||
|         // 返回目标结点 | ||||
|         return cur; | ||||
|     } | ||||
|  | ||||
|     /* 插入结点 */ | ||||
|     TreeNode* insert(int num) { | ||||
|         // 若树为空,直接提前返回 | ||||
|         if (root == nullptr) return nullptr; | ||||
|         TreeNode *cur = root, *pre = nullptr; | ||||
|         // 循环查找,越过叶结点后跳出 | ||||
|         while (cur != nullptr) { | ||||
|             // 找到重复结点,直接返回 | ||||
|             if (cur->val == num) return nullptr; | ||||
|             pre = cur; | ||||
|             // 插入位置在 root 的右子树中 | ||||
|             if (cur->val < num) cur = cur->right; | ||||
|             // 插入位置在 root 的左子树中 | ||||
|             else cur = cur->left; | ||||
|         } | ||||
|         // 插入结点 val | ||||
|         TreeNode* node = new TreeNode(num); | ||||
|         if (pre->val < num) pre->right = node; | ||||
|         else pre->left = node; | ||||
|         return node; | ||||
|     } | ||||
|  | ||||
|     /* 删除结点 */ | ||||
|     TreeNode* remove(int num) { | ||||
|         // 若树为空,直接提前返回 | ||||
|         if (root == nullptr) return nullptr; | ||||
|         TreeNode *cur = root, *pre = nullptr; | ||||
|         // 循环查找,越过叶结点后跳出 | ||||
|         while (cur != nullptr) { | ||||
|             // 找到待删除结点,跳出循环 | ||||
|             if (cur->val == num) break; | ||||
|             pre = cur; | ||||
|             // 待删除结点在 root 的右子树中 | ||||
|             if (cur->val < num) cur = cur->right; | ||||
|             // 待删除结点在 root 的左子树中 | ||||
|             else cur = cur->left; | ||||
|         } | ||||
|         // 若无待删除结点,则直接返回 | ||||
|         if (cur == nullptr) return nullptr; | ||||
|         // 子结点数量 = 0 or 1 | ||||
|         if (cur->left == nullptr || cur->right == nullptr) { | ||||
|             // 当子结点数量 = 0 / 1 时, child = nullptr / 该子结点 | ||||
|             TreeNode* child = cur->left != nullptr ? cur->left : cur->right; | ||||
|             // 删除结点 cur | ||||
|             if (pre->left == cur) pre->left = child; | ||||
|             else pre->right = child; | ||||
|         } | ||||
|         // 子结点数量 = 2 | ||||
|         else { | ||||
|             // 获取中序遍历中 cur 的下一个结点 | ||||
|             TreeNode* nex = min(cur->right); | ||||
|             int tmp = nex->val; | ||||
|             // 递归删除结点 nex | ||||
|             remove(nex->val); | ||||
|             // 将 nex 的值复制给 cur | ||||
|             cur->val = tmp; | ||||
|         } | ||||
|         return cur; | ||||
|     } | ||||
|  | ||||
|     /* 获取最小结点 */ | ||||
|     TreeNode* min(TreeNode* root) { | ||||
|         if (root == nullptr) return root; | ||||
|         // 循环访问左子结点,直到叶结点时为最小结点,跳出 | ||||
|         while (root->left != nullptr) { | ||||
|             root = root->left; | ||||
|         } | ||||
|         return root; | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Driver Code */ | ||||
| int main() { | ||||
|     /* 初始化二叉搜索树 */ | ||||
|     vector<int> nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; | ||||
|     BinarySearchTree* bst = new BinarySearchTree(nums); | ||||
|     cout << endl << "初始化的二叉树为\n" << endl; | ||||
|     PrintUtil::printTree(bst->getRoot()); | ||||
|  | ||||
|     /* 查找结点 */ | ||||
|     TreeNode* node = bst->search(5); | ||||
|     cout << endl << "查找到的结点对象为 " << node << ",结点值 = " << node->val << endl; | ||||
|  | ||||
|     /* 插入结点 */ | ||||
|     node = bst->insert(16); | ||||
|     cout << endl << "插入结点 16 后,二叉树为\n" << endl; | ||||
|     PrintUtil::printTree(bst->getRoot()); | ||||
|  | ||||
|     /* 删除结点 */ | ||||
|     bst->remove(1); | ||||
|     cout << endl << "删除结点 1 后,二叉树为\n" << endl; | ||||
|     PrintUtil::printTree(bst->getRoot()); | ||||
|     bst->remove(2); | ||||
|     cout << endl << "删除结点 2 后,二叉树为\n" << endl; | ||||
|     PrintUtil::printTree(bst->getRoot()); | ||||
|     bst->remove(4); | ||||
|     cout << endl << "删除结点 4 后,二叉树为\n" << endl; | ||||
|     PrintUtil::printTree(bst->getRoot()); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -6,3 +6,35 @@ | ||||
|  | ||||
| #include "../include/include.hpp" | ||||
|  | ||||
|  | ||||
| /* Driver Code */ | ||||
| int main() { | ||||
|     /* 初始化二叉树 */ | ||||
|     // 初始化结点 | ||||
|     TreeNode* n1 = new TreeNode(1); | ||||
|     TreeNode* n2 = new TreeNode(2); | ||||
|     TreeNode* n3 = new TreeNode(3); | ||||
|     TreeNode* n4 = new TreeNode(4); | ||||
|     TreeNode* n5 = new TreeNode(5); | ||||
|     // 构建引用指向(即指针) | ||||
|     n1->left = n2; | ||||
|     n1->right = n3; | ||||
|     n2->left = n4; | ||||
|     n2->right = n5; | ||||
|     cout << endl << "初始化二叉树\n" << endl; | ||||
|     PrintUtil::printTree(n1); | ||||
|  | ||||
|     /* 插入与删除结点 */ | ||||
|     TreeNode* P = new TreeNode(0); | ||||
|     // 在 n1 -> n2 中间插入结点 P | ||||
|     n1->left = P; | ||||
|     P->left = n2; | ||||
|     cout << endl << "插入结点 P 后\n" << endl; | ||||
|     PrintUtil::printTree(n1); | ||||
|     // 删除结点 P | ||||
|     n1->left = n2; | ||||
|     cout << endl << "删除结点 P 后\n" << endl; | ||||
|     PrintUtil::printTree(n1); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -6,3 +6,39 @@ | ||||
|  | ||||
| #include "../include/include.hpp" | ||||
|  | ||||
| /* 层序遍历 */ | ||||
| vector<int> hierOrder(TreeNode* root) { | ||||
|     // 初始化队列,加入根结点 | ||||
|     queue<TreeNode*> queue; | ||||
|     queue.push(root); | ||||
|     // 初始化一个列表,用于保存遍历序列 | ||||
|     vector<int> vec; | ||||
|     while (!queue.empty()) { | ||||
|         TreeNode* node = queue.front(); | ||||
|         queue.pop();  // 队列出队 | ||||
|         vec.push_back(node->val);            // 保存结点 | ||||
|         if (node->left != NULL) | ||||
|             queue.push(node->left);    // 左子结点入队 | ||||
|         if (node->right != NULL) | ||||
|             queue.push(node->right);   // 右子结点入队 | ||||
|     } | ||||
|     return vec; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Driver Code */ | ||||
| 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 }); | ||||
|     cout << endl << "初始化二叉树\n" << endl; | ||||
|     PrintUtil::printTree(root); | ||||
|  | ||||
|     /* 层序遍历 */ | ||||
|     vector<int> vec = hierOrder(root); | ||||
|     cout << endl << "层序遍历的结点打印序列 = "; | ||||
|     PrintUtil::printVector(vec); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -6,3 +6,63 @@ | ||||
|  | ||||
| #include "../include/include.hpp" | ||||
|  | ||||
| // 初始化列表,用于存储遍历序列 | ||||
| vector<int> vec; | ||||
|  | ||||
| /* 前序遍历 */ | ||||
| void preOrder(TreeNode* root) { | ||||
|     if (root == nullptr) return; | ||||
|     // 访问优先级:根结点 -> 左子树 -> 右子树 | ||||
|     vec.push_back(root->val); | ||||
|     preOrder(root->left); | ||||
|     preOrder(root->right); | ||||
| } | ||||
|  | ||||
| /* 中序遍历 */ | ||||
| void inOrder(TreeNode* root) { | ||||
|     if (root == nullptr) return; | ||||
|     // 访问优先级:左子树 -> 根结点 -> 右子树 | ||||
|     inOrder(root->left); | ||||
|     vec.push_back(root->val); | ||||
|     inOrder(root->right); | ||||
| } | ||||
|  | ||||
| /* 后序遍历 */ | ||||
| void postOrder(TreeNode* root) { | ||||
|     if (root == nullptr) return; | ||||
|     // 访问优先级:左子树 -> 右子树 -> 根结点 | ||||
|     postOrder(root->left); | ||||
|     postOrder(root->right); | ||||
|     vec.push_back(root->val); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Driver Code */ | ||||
| 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}); | ||||
|     cout << endl << "初始化二叉树\n" << endl; | ||||
|     PrintUtil::printTree(root); | ||||
|  | ||||
|     /* 前序遍历 */ | ||||
|     vec.clear(); | ||||
|     preOrder(root); | ||||
|     cout << endl << "前序遍历的结点打印序列 = "; | ||||
|     PrintUtil::printVector(vec); | ||||
|  | ||||
|     /* 中序遍历 */ | ||||
|     vec.clear(); | ||||
|     inOrder(root); | ||||
|     cout << endl << "中序遍历的结点打印序列 = "; | ||||
|     PrintUtil::printVector(vec); | ||||
|  | ||||
|     /* 后序遍历 */ | ||||
|     vec.clear(); | ||||
|     postOrder(root); | ||||
|     cout << endl << "后序遍历的结点打印序列 = "; | ||||
|     PrintUtil::printVector(vec); | ||||
|      | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user