代碼函數功能順序如下:
1:destroy:遞歸刪除樹
2:copy:復制二叉樹
3:preOrder:遞歸前序遍歷
4:inOrder:遞歸中序遍歷
5:postOrder:遞歸后續遍歷
6:levelOrder:BFS層序遍歷
7:mergeTrees:合并樹
8:getRoot:獲取根節點
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{int val; // 節點值TreeNode *left; // 左子樹TreeNode *right; // 右子樹TreeNode(int x) // 構造函數{val = x;left = nullptr;right = nullptr;}
};
// class定義類
class BinaryTree
{
private:TreeNode *root; // 定義根節點,根節點是私有的,外部不能直接訪問// 遞歸刪除樹void destroy(TreeNode *node) // 參數是正在處理的二叉樹結點{if (node) // 在節點存在(不為空)的情況下{destroy(node->left); // 遞歸刪除左子樹destroy(node->right); // 遞歸刪除右子樹delete node; // 刪除當前節點}}// 遞歸復制二叉樹TreeNode *copy(TreeNode *node) // 輸入原二叉樹的某個結點指針// 返回復制后的新二叉樹對應節點指針{if (!node){return nullptr;}TreeNode *newNode = new TreeNode(node->val);newNode->left = copy(node->left);newNode->right = copy(node->right);return newNode;}public:BinaryTree() : root(nullptr) {}// 構造函數,初始化根節點為空// 遞歸前序遍歷void preOrder(TreeNode *node = nullptr){if (!node) // 如果當前是空節點,則返回{// 如果當前節點為空,停止遞歸if (!root){return;}node = root; // 如果當前節點不為空,則將當前節點設為根節點}cout << node->val << " "; // 輸出當前節點值if (node->left){preOrder(node->left); // 遞歸遍歷左子樹}if (node->right){preOrder(node->right); // 遞歸遍歷右子樹}}// 遞歸中序遍歷void inOrder(TreeNode *node = nullptr){if (!node){if (!root){return;}node = root;}if (node->left){inOrder(node->left);}cout << node->val << " ";if (node->right){inOrder(node->right);}}// 遞歸后序遍歷void postOrder(TreeNode *node = nullptr){if (!node){if (!root){return;}node = root;}if (node->left){postOrder(node->left);}if (node->right){postOrder(node->right);}cout << node->val << " ";}// 層序遍歷(BFS)void levelOrder(const vector<int> &nodes) // 參數用來存儲二叉樹的層序遍歷序列{if (nodes.empty() || nodes[0] == -1){root = nullptr;return;}root = new TreeNode(nodes[0]);// 根節點是第一個元素queue<TreeNode *> q;// 使用隊列進行層序遍歷q.push(root);// 放入第一個元素int i = 1;while (!q.empty() && i < nodes.size()){TreeNode *current = q.front();// 獲取當前節點,起名為currentq.pop(); // 彈出隊頭if (i < nodes.size() && nodes[i] != -1){ // 如果當前節點有左子樹current->left = new TreeNode(nodes[i]);// 創建左子樹,值為nodes[i]q.push(current->left);// 將左子樹放入隊列}i++; // i指向下一個元素// 右子樹同理if (i < nodes.size() && nodes[i] != -1){current->right = new TreeNode(nodes[i]);q.push(current->right);}i++;}}// 合并兩棵樹// void,直接修改當前數的值,把他與other合并// other樹會清空(root指針被設為nullptr)void mergeTrees(BinaryTree &other, int mergeValue){// 參數other是另一個二叉樹,mergeValue是合并后的新根節點的值if (!root){root = other.root; // 如果當前樹為空,直接將other樹賦值給當前樹other.root = nullptr; // other樹清空return;}TreeNode *newRoot = new TreeNode(mergeValue);// 創建新根節點,值為mergeValue,作為合并后的根節點newRoot->left = root;// 新根節點的左子樹為當前樹的根節點newRoot->right = other.root;// 新根節點的右子樹為other樹的根節點root = newRoot;// 將新根節點賦值給當前樹的根節點other.root = nullptr;// other樹清空}// 析構函數~BinaryTree() { destroy(root); } // 析構函數,刪除樹// 獲取根節點TreeNode *getRoot() { return root; } // 獲取根節點
};
int main()
{// 測試1: 構造空樹BinaryTree emptyTree;cout << "Empty tree pre-order: ";emptyTree.preOrder(); // 應無輸出cout << endl;// 測試2: 從層序遍歷數組構造二叉樹vector<int> nodes1 = {1, 2, 3, -1, 4, 5, 6}; // -1表示空節點BinaryTree tree1;tree1.levelOrder(nodes1); // 構建樹cout << "Tree1 Pre-order(recursive): ";tree1.preOrder();cout << endl;cout << "Tree1 In-order(recursive): ";tree1.inOrder();cout << endl;cout << "Tree1 Post-order(recursive): ";tree1.postOrder();cout << endl;// 測試3: 復制構造函數BinaryTree tree2;tree2.levelOrder({10, 11, 12, 13, -1, 14}); // 構建另一棵樹cout << "\nTree2 Level-order built: 10,11,12,13,-1,14" << endl;cout << "Tree2 Pre-order: ";tree2.preOrder();cout << endl;// 測試4: 合并兩棵樹cout << "\nMerging Tree1 and Tree2 with new root value 100..." << endl;tree1.mergeTrees(tree2, 100);cout << "Merged Tree Pre-order: ";tree1.preOrder(); // 應顯示: 100 1 2 4 3 5 6 10 11 13 12 14cout << endl;// 測試5: 檢查tree2是否被清空cout << "\nTree2 after merging (should be empty): ";tree2.preOrder(); // 應無輸出cout << endl;// 測試6: 析構函數(自動調用,無需顯式測試)cout << "\nAll trees will be automatically destroyed when exiting main()" << endl;return 0;
}