二叉树的遍历
二叉树的遍历
二叉树的遍历一般分为三种遍历方法,即先序遍历、中序遍历和后序遍历。在中序遍历中,一个节点的前驱,是其左子树的最右下角结点,后继,是其右子树的最左下角结点。
在后序遍历中,
• 若结点是根结点,则其后继为空;
• 若结点是双亲的右子树,或是左子树但双亲无右子树,则其后继为双亲结点;
• 若结点是双亲的左子树且双亲有右子树,则其后继为右子树按后序遍历的第一个结点
二叉树的遍历实现如下:
#include <stack>
#include <queue>
/*
*@struct
*@brief 二叉树结点
*/
typedef struct binary_tree_node_t
{
binary_tree_node_t *lchild; /* 左孩子 */
binary_tree_node_t *rchild; /* 右孩子 */
void* data; /* 结点的数据 */
}binary_tree_node_t;
/**
* @brief 先序遍历,递归.
* @param[in] root 根结点
* @param[in] visit 访问数据元素的函数指针
* @return 无
*/
void pre_order_r(const binary_tree_node_t *root, int (*visit)(void*))
{
if(root != NULL)
{
(void)visit(root->data);
pre_order_r(root->lchild, visit);
pre_order_r(root->rchild, visit);
}
}
/**
* @brief 中序遍历,递归.
*/
void in_order_r(const binary_tree_node_t *root, int (*visit)(void*))
{
if(root != NULL)
{
pre_order_r(root->lchild, visit);
(void)visit(root->data);
pre_order_r(root->rchild, visit);
}
}
/**
* @brief 后序遍历,递归.
*/
void post_order_r(const binary_tree_node_t *root, int (*visit)(void*))
{
if(root != NULL)
{
pre_order_r(root->lchild, visit);
pre_order_r(root->rchild, visit);
(void)visit(root->data);
}
}
/**
* @brief 先序遍历,非递归.
*/
void pre_order(const binary_tree_node_t *root, int (*visit)(void*))
{
const binary_tree_node_t *p;
std::stack<const binary_tree_node_t *> s;
p = root;
if(p != NULL)
{
s.push(p);
}
while(!s.empty())
{
p = s.top();
s.pop();
visit(p->data);
if(p->rchild != NULL)
{
s.push(p->rchild);
}
if(p->lchild != NULL)
{
s.push(p->lchild);
}
}
}
/**
* @brief 中序遍历,非递归.
*/
void in_order(const binary_tree_node_t *root, int (*visit)(void*))
{
const binary_tree_node_t *p;
std::stack<const binary_tree_node_t *> s;
p = root;
while(!s.empty() || p!=NULL)
{
if(p != NULL)
{
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
s.pop();
visit(p->data);
p = p->rchild;
}
}
}
/**
* @brief 后序遍历,非递归.
*/
void post_order(const binary_tree_node_t *root, int (*visit)(void*))
{
/* p,正在访问的结点,q,刚刚访问过的结点 */
const binary_tree_node_t *p, *q;
std::stack<const binary_tree_node_t *> s;
p = root;
do {
while(p != NULL)
{
/* 往左下走 */
s.push(p);
p = p->lchild;
}
q = NULL;
while(!s.empty())
{
p = s.top();
s.pop();
/* 右孩子不存在或已被访问,访问之 */
if(p->rchild == q)
{
visit(p->data);
q = p; /* 保存刚访问过的结点 */
}
else
{
/* 当前结点不能访问,需第二次进栈 */
s.push(p);
/* 先处理右子树 */
p = p->rchild;
break;
}
}
}while(!s.empty());
}
/**
* @brief 层次遍历,也即 BFS.
*
* 跟先序遍历一模一样,唯一的不同是栈换成了队列
*/
void level_order(const binary_tree_node_t *root, int (*visit)(void*))
{
const binary_tree_node_t *p;
std::queue<const binary_tree_node_t *> q;
p = root;
if(p != NULL)
{
q.push(p);
}
while(!q.empty())
{
p = q.front();
q.pop();
visit(p->data);
if(p->lchild != NULL)
{
/* 先左后右或先右后左无所谓 */
q.push(p->lchild);
}
if(p->rchild != NULL)
{
q.push(p->rchild);
}
}
}
二叉树的常见问题及其解决程序
【递归】二叉树的先序建立及遍历
在JAVA中实现的二叉树结构
【非递归】二叉树的建立及遍历
二叉树递归实现与二重指针
二叉树先序中序非递归算法
轻松搞定面试中的二叉树题目
本文永久更新链接地址:
评论暂时关闭