二叉树的先序遍历
Posted 、工藤新一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的先序遍历相关的知识,希望对你有一定的参考价值。
二叉树的三种遍历方式,其中每一种遍历方式都有三种实现方式。
节点定义:
struct TreeNode
{
int val;
TreeNode *left,*right;
TreeNode(int val){
this->val = val;
this ->left = this->right = NULL;
}
};
先序遍历
以上面这张图为例:我们讲讲树的三种遍历方式:
先序遍历:先访问根节点,然后访问左孩子,最后访问右孩子。
所以,上面遍历的结果是:GEDACHS。
下面,我们来看看具体代码实现
1.递归实现
void preOrder(TreeNode *root){
if (root==NULL)
return;
cout<<root->val<<endl;
preOrder(root->left);
preOrder(root->right);
}
2.使用辅助栈
实现思路:1.将根节点入栈
2.每次从栈顶弹出一个节点,访问该节点
3.把当前节点的右孩子入栈
4.把当前节点的左孩子入栈
具体实现:
void preOrder2(TreeNode *root){
if (root == NULL)
return;
stack<TreeNode*> stk; //开辟一个栈空间
stk.push(root);
while(!stk.empty()){
TreeNode* pNode = stk.pop();
cout<<pNode->val;
if (pNode->right!=NULL)
stk.push(pNode->right);
if (pNode->left!=NULL)
stk.push(pNode->left);
}
}
3.Morris遍历
Morris遍历,常数的空间即可在O(n)时间内完成二叉树的遍历。
O(1)空间进行遍历困难之处在于在遍历的子结点的时候如何重新返回其父节点?
在Morris遍历算法中,通过修改叶子结点的左右空指针来指向其前驱或者后继结点来实现的。
其本质:线索二叉树(Threaded Binary Tree),通过利用叶子节点空的right指针,指向中序遍历的后继节点,从而避免了对 stack 的依赖。
具体实现:
void preOrder(TreeNode* root){
if (root == NULL)
return;
TreeNode* pNode = root;
while(pNode != NULL){
if (pNode->left == NULL)
{
cout<<pNode->val<<endl;
pNode = pNode->right;
}
else{
TreeNode* pPre = pNode->left;
while(pPre->right != NULL && pPre->right != pNode){
pPre = pPre->right;
}
if (pPre->right == NULL)
{
/* code */
pPre->right = pNode;
cout<<pNode->val<<endl;
pNode = pNode->left;
}
else{
pPre->right = NULL;
pNode = pNode->right;
}
}
}
}
附:二叉树的先序遍历
附:二叉树的中序遍历
附:二叉树的后序遍历
附:二叉树的三种遍历对比及用图片展现说明
以上是关于二叉树的先序遍历的主要内容,如果未能解决你的问题,请参考以下文章
已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列