二叉树的使用,在数据结构中是比较常见的。这里列举了二叉树的四种遍历方式:前序,中序,后序遍历(递归和非递归的方式)以及层次遍历的方法,供大家参考。
先给出文章中所用的二叉树:
8
/ \
6 10
/ \ / \
5 7 9 11
\ / / \
12 16 13 15
\
14
首先是前序遍历:
递归的方式:
1. 遍历根节点
2. 遍历左子树
3. 遍历右子树
void preOrser(TreeNode *s)
{
if ( s != nullptr )
{
cout << s->val << " ";
preOrser(s->left);
preOrser(s->right);
}
}
非递归的方式:详细解释见注释
void preOrser(node *t)
{
// 用于保存节点
stack<node*> s;
if ( t == nullptr )
return;
// 当指针非空,或者 栈非空时 继续遍历
while( t || !s.empty() )
{
// 一直找到最左端
while(t)
{
// 因为是先序遍历,所以需要先打印节点的值
cout << t->val << " " ;
s.push( t );
t = t->left;
} // 当空节点时,跳出循环
t = s.top();
s.pop();
// 找到右孩子
t = t->right;
}
}
递归的方式:
1. 遍历左子树
2. 遍历根节点
3. 遍历右子树
void midOrder(TreeNode *s)
{
if ( s != nullptr )
{
midOrder(s->left);
cout << s->val << " ";
midOrder(s->right);
}
}
// 完成了二叉树的中序遍历的非递归形式
// 通过 栈 能实现二叉树的遍历过程
void midOrder(node *t)
{
// 用于储存遍历的元素
stack<node*> sta;
while( t || !sta.empty() )
{
if ( t != nullptr )
{
sta.push(t);
t = t->left;
}
else
{
t = sta.top();
sta.pop();
cout << t->val << " ";
t = t->right;
}
}
}
再则是后续遍历:
1. 遍历左子树
2. 遍历右子树
3. 遍历根节点void postOrder(TreeNode *s)
{
if ( s != nullptr )
{
postOrder(s->left);
postOrder(s->right);
cout << s->val << " ";
}
}
//非递归实现二叉树后续遍历,需要借助两个容器来实现
//第一个栈按前序遍历将二叉树节点压栈
//第二个容器是当第一个栈要出栈的时候,将当前出栈的节点压栈到第二个容器
//如果当前节点存在左孩子节点,则压栈到第一个栈
//如果当前节点存在右孩子节点,则压栈到第一个栈
//最后当第一个栈为空的时候,这时候遍历第二个容器,让第二个容器一直输出当前节点值
void postOrser(node *t)
{
stack<node*> pre;
vector<int> post;
if ( t == nullptr )
return;
pre.push(t);
while( !pre.empty() )
{
node* p;
p = pre.top();
post.push_back(p->val);
pre.pop();
if ( p->left != nullptr )
pre.push(p->left);
if ( p->right != nullptr )
pre.push(p->right);
}
for ( auto it = post.end() -1; it >= post.begin(); it-- )
cout << *it << " ";
}
层次遍历就是按照二叉树的高度,从上往下,从左向右依次遍历每一个节点
vector<int> PrintFromTopToBottom(TreeNode *root)
{
vector<struct TreeNode*> v;
vector<int> s;
if ( root == nullptr )
return s;
v.push_back(root);
int i = 0;
while(i != v.size())
{
if ( v[i]->left != nullptr )
{
v.push_back(v[i]->left);
}
if ( v[i]->right != nullptr )
{
v.push_back(v[i]->right);
}
i++;
}
for ( int i = 0 ; i < v.size();i++ )
{
s.push_back(v[i]->val);
}
return s;
}
以上所有程序的执行结果对应上面的二叉树为: