写一个栈与递归的转换的c++代码
时间: 2023-10-11 07:11:52 浏览: 35
以下是一个栈与递归的转换的c++代码示例:
```c++
#include <iostream>
#include <stack>
using namespace std;
void recursive_function(int num) {
if (num == 0) return;
// 其他递归操作
recursive_function(num - 1);
}
void stack_function(int num) {
stack<int> stk;
while (num > 0) {
// 其他栈操作
stk.push(num);
num--;
}
while (!stk.empty()) {
// 其他栈操作
int top_num = stk.top();
stk.pop();
}
}
int main() {
int num = 10;
recursive_function(num);
stack_function(num);
return 0;
}
```
该示例中,我们定义了一个递归函数和一个使用栈实现的函数。在递归函数中,我们简单地将 num 值递归减少一直到 0。在使用栈的函数中,我们使用一个 while 循环将 num 值压入栈中,然后再使用一个 while 循环将栈内元素取出,实现逆序输出 num 值。
相关问题
用C++写一个中缀表达式转换抽象语法树代码,要求是输入任意中缀表达式都可实现
以下是使用C++实现中缀表达式转换抽象语法树的示例代码。注意:此代码仅支持包含加减乘除四个基本运算符的中缀表达式。
```cpp
#include <iostream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
// 定义操作符的优先级
int priority(char op) {
if (op == '+' || op == '-') {
return 1;
}
else if (op == '*' || op == '/') {
return 2;
}
else {
return 0;
}
}
// 将中缀表达式转换为后缀表达式
vector<string> infixToPostfix(string expr) {
stack<char> opStack;
vector<string> postfixExpr;
int len = expr.length();
for (int i = 0; i < len; i++) {
char ch = expr[i];
if (isdigit(ch)) {
// 数字直接加入后缀表达式
string numStr;
while (i < len && isdigit(expr[i])) {
numStr += expr[i++];
}
postfixExpr.push_back(numStr);
i--;
}
else if (ch == '(') {
// 左括号入栈
opStack.push(ch);
}
else if (ch == ')') {
// 右括号弹出栈顶操作符直到左括号
while (!opStack.empty() && opStack.top() != '(') {
postfixExpr.push_back(string(1, opStack.top()));
opStack.pop();
}
opStack.pop(); // 弹出左括号
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
// 操作符入栈,弹出优先级大于等于该操作符的栈顶操作符
while (!opStack.empty() && priority(opStack.top()) >= priority(ch)) {
postfixExpr.push_back(string(1, opStack.top()));
opStack.pop();
}
opStack.push(ch);
}
}
// 将栈中剩余操作符加入后缀表达式
while (!opStack.empty()) {
postfixExpr.push_back(string(1, opStack.top()));
opStack.pop();
}
return postfixExpr;
}
// 定义抽象语法树的节点
struct TreeNode {
char op; // 操作符
int num; // 数字
TreeNode* left; // 左子节点
TreeNode* right; // 右子节点
TreeNode(char op, TreeNode* left, TreeNode* right) {
this->op = op;
this->num = 0;
this->left = left;
this->right = right;
}
TreeNode(int num) {
this->op = ' ';
this->num = num;
this->left = nullptr;
this->right = nullptr;
}
};
// 将后缀表达式转换为抽象语法树
TreeNode* postfixToAST(vector<string> postfixExpr) {
stack<TreeNode*> nodeStack;
int len = postfixExpr.size();
for (int i = 0; i < len; i++) {
string str = postfixExpr[i];
if (isdigit(str[0])) {
// 数字节点入栈
nodeStack.push(new TreeNode(stoi(str)));
}
else {
// 操作符节点弹出两个子节点后入栈
TreeNode* rightNode = nodeStack.top();
nodeStack.pop();
TreeNode* leftNode = nodeStack.top();
nodeStack.pop();
nodeStack.push(new TreeNode(str[0], leftNode, rightNode));
}
}
return nodeStack.top();
}
// 递归输出抽象语法树
void printAST(TreeNode* node, int indent) {
if (node == nullptr) {
return;
}
printAST(node->right, indent + 4);
cout << string(indent, ' ');
if (node->op != ' ') {
cout << node->op << endl;
}
else {
cout << node->num << endl;
}
printAST(node->left, indent + 4);
}
int main() {
string expr;
cout << "请输入中缀表达式:";
getline(cin, expr);
vector<string> postfixExpr = infixToPostfix(expr);
cout << "后缀表达式:";
for (string str : postfixExpr) {
cout << str << " ";
}
cout << endl;
TreeNode* root = postfixToAST(postfixExpr);
cout << "抽象语法树:" << endl;
printAST(root, 0);
return 0;
}
```
示例输入:
```
请输入中缀表达式:(2+3)*4-5/2
```
示例输出:
```
后缀表达式:2 3 + 4 * 5 2 / -
抽象语法树:
-
* /
+ 4 5 2
2 3
```
实现树与二叉树的转换、树的前序、后序的递归和非递归算法,应包含建树的实现,写出代码
好的,我来为您解答。
首先,我们需要定义树和二叉树的结构体:
```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();
}
}
```
完整代码如下: