C++学习——二叉树先,中,后序遍历(递归和非递归)
`
一、先序遍历
遍历顺序:头左右
递归序
先头节点,再左节点,再右节点。
代码如下(示例):
void preorderDG(TreeNode* root)
{
if (root == nullptr) return;
if (root != NULL) cout << root->val<<" ";
if(root->left != NULL) preorderDG(root->left);
if(root->right != NULL) preorderDG(root->right);
}
非递归序
初始化:将头节点放入栈中;
S1:从栈中弹出一个节点
S2:打印该节点
S3:若弹出节点存在左右节点,则先右再左压入栈中
S4:重复S1到S3
代码如下(示例):
void preorder(TreeNode* root)
{
if (root == nullptr) return;
//定义栈
stack<TreeNode*> s;
//定义中间节点变量r
TreeNode* r = new TreeNode();
//初始化
s.push(root);
r = s.top();
cout << r->val << " ";
s.pop();
//执行循环
while (!(s.empty() && r->left == NULL && r->right == NULL))
{
//先右
if (r->right != NULL) s.push(r->right);
//再左
if (r->left != NULL) s.push(r->left);
if (!s.empty())
{
r = s.top();
cout << r->val << " ";
s.pop();
}
}
}
二、中序遍历
左头右
1.递归序
代码如下(示例):
void InorderDG(TreeNode* root)
{
if (root != NULL)
{
if (root->left != NULL) InorderDG(root->left);
cout << root->val<<" ";
if (root->right != NULL) InorderDG(root->right);
}
}
2.非递归序
初始化:将头节点的左子树节点全部放入栈中
S1:弹出栈顶节点,并打印;
S2:若弹出节点存在右子树,则将弹出节点右子树的全部左子树放入栈中;
S3:重复S1到S2
代码如下(示例):
void Inorder(TreeNode* root)
{
if (root == nullptr) return;
stack<TreeNode*> s;
TreeNode* r = new TreeNode();
TreeNode* temp = new TreeNode();
s.push(root);
r = s.top();
while (r->left != nullptr)
{
r = r->left;
s.push(r);
}
while (!(s.empty() && r->left == NULL && r->right == NULL))
{
r = s.top();
s.pop();
cout << r->val << " ";
//若弹出节点存在右子树
if (r->right != nullptr)
{
temp = r->right;
s.push(temp);
while (temp->left != nullptr)
{
temp = temp->left;
s.push(temp);
}
}
}
}
三、后序遍历
左右头
1.递归序
代码如下(示例):
void PostorderDG(TreeNode* root)
{
if (root != NULL)
{
if (root->left != NULL) PostorderDG(root->left);
if (root->right != NULL) PostorderDG(root->right);
cout << root->val << " ";
}
}
2.非递归序(需要两个栈)
初始化:准备栈1和栈2将头节点放入栈1中。
S1:从栈1中弹出节点放入栈2中;
S2:若弹出节点存在左右节点,则先压左再压右节点在栈1中;
S3:重复S1到S2;
S4:依次弹出栈2中的元素,打印
代码如下(示例):
void Postorder(TreeNode* root)
{
if (root == nullptr) return;
stack<TreeNode*> s;
stack<TreeNode*> s1;
TreeNode* r = new TreeNode();
s.push(root);
r = s.top();
s1.push(r);
s.pop();
while (!(s.empty() && r->left == NULL && r->right == NULL))
{
if (r->left != NULL) s.push(r->left);
if (r->right != NULL) s.push(r->right);
if (!s.empty())
{
r = s.top();
s1.push(r);
s.pop();
}
}
//打印收集栈
while (!s1.empty())
{
r = s1.top();
cout << r->val << " ";
s1.pop();
}
return;
}