实现树与二叉树的转换、树的前序、后序的递归和非递归算法,应包含建树的实现,写出代码
时间: 2024-03-23 12:36:46 浏览: 126
好的,我来为您解答。
首先,我们需要定义树和二叉树的结构体:
```c++
// 树的结构体
struct TreeNode {
int val;
vector<TreeNode*> children;
TreeNode(int x) : val(x) {}
};
// 二叉树的结构体
struct BinaryTreeNode {
int val;
BinaryTreeNode* left;
BinaryTreeNode* right;
BinaryTreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
```
接下来,我们分别实现树与二叉树的转换,以及树的前序、后序的递归和非递归算法。
1. 树与二叉树的转换
将树转换为二叉树的方法是:对于每个节点,将其第一个子节点作为左子树,将其其他子节点依次作为该左子树的右子节点。例如,对于如下的树:
```
1
/ | \
2 3 4
/ \
5 6
```
转换后的二叉树如下:
```
1
/
2
/ \
5 6
/ \
3 4
```
代码实现如下:
```c++
BinaryTreeNode* treeToBinaryTree(TreeNode* root) {
if (!root) return nullptr;
BinaryTreeNode* bRoot = new BinaryTreeNode(root->val);
if (!root->children.empty()) {
bRoot->left = treeToBinaryTree(root->children[0]);
BinaryTreeNode* p = bRoot->left;
for (int i = 1; i < root->children.size(); i++) {
p->right = treeToBinaryTree(root->children[i]);
p = p->right;
}
}
return bRoot;
}
```
将二叉树转换为树的方法是:对于每个节点,将其左子树作为第一个子节点,将其右子树的所有节点依次作为该第一个子节点的兄弟节点。例如,对于上面的二叉树,转换后的树如下:
```
1
/ | \
2 3 4
/ \
5 6
```
代码实现如下:
```c++
TreeNode* binaryTreeToTree(BinaryTreeNode* root) {
if (!root) return nullptr;
TreeNode* tRoot = new TreeNode(root->val);
if (root->left) {
tRoot->children.push_back(binaryTreeToTree(root->left));
BinaryTreeNode* p = root->left->right;
while (p) {
tRoot->children.push_back(binaryTreeToTree(p));
p = p->right;
}
}
return tRoot;
}
```
2. 树的前序、后序的递归算法
树的前序遍历:先输出当前节点的值,再依次遍历每个子节点。代码实现如下:
```c++
void preorderTraversal(TreeNode* root) {
if (!root) return;
cout << root->val << " ";
for (auto child : root->children) {
preorderTraversal(child);
}
}
```
树的后序遍历:先依次遍历每个子节点,再输出当前节点的值。代码实现如下:
```c++
void postorderTraversal(TreeNode* root) {
if (!root) return;
for (auto child : root->children) {
postorderTraversal(child);
}
cout << root->val << " ";
}
```
3. 树的前序、后序的非递归算法
树的前序遍历的非递归算法使用栈实现。遍历时,先将根节点压入栈中,然后弹出栈顶元素并输出,再将其子节点依次压入栈中(注意要从右往左压入,保证左子节点在右子节点之前被访问)。代码实现如下:
```c++
void preorderTraversal2(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s;
s.push(root);
while (!s.empty()) {
TreeNode* p = s.top();
s.pop();
cout << p->val << " ";
for (int i = p->children.size() - 1; i >= 0; i--) {
s.push(p->children[i]);
}
}
}
```
树的后序遍历的非递归算法比较复杂。我们可以使用两个栈来实现,具体方法如下:
1. 将根节点压入第一个栈中。
2. 从第一个栈中弹出栈顶元素,并依次将其子节点压入第一个栈中。
3. 每次压入第一个栈中的节点,同时将其压入第二个栈中。
4. 当第一个栈为空时,第二个栈中的元素依次弹出并输出。
代码实现如下:
```c++
void postorderTraversal2(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s1, s2;
s1.push(root);
while (!s1.empty()) {
TreeNode* p = s1.top();
s1.pop();
s2.push(p);
for (auto child : p->children) {
s1.push(child);
}
}
while (!s2.empty()) {
cout << s2.top()->val << " ";
s2.pop();
}
}
```
完整代码如下:
阅读全文