递归形式
递归形式遍历比较简单,不做详细论述。
前序遍历
void Preorder(treenode* root) //前序
{
if (root != NULL)
{
printf("%c", root->data);
Preorder(root->left);
Preorder(root->right);
}
中序遍历
}
void Inorder(treenode* root) //中序
{
if (root != NULL)
{
Inorder(root->left);
printf("%c", root->data);
Inorder(root->right);
}
}
后序遍历
void Postorder(treenode* root) //后序
{
if (root != NULL)
{
Postorder(root->left);
Postorder(root->right);
printf("%c", root->data);
}
}
非递归形式
前序遍历
开始不断向左孩子遍历并入栈,在入栈的同时打印节点数据,直到左孩子为空,此时获取栈顶节点,并将其出栈,判断其有无右孩子,如果无右孩子,就再次获取栈顶节点并出栈,重复上述操作;如果有右孩子就将其入栈,并不断遍历其左孩子直到为空,重复上述操作,直到栈为空。
void PreOrder(treenode* root)
{
if (root == NULL)
return;
treenode* p = root;
stack<treenode *> s;
while (!s.empty() || p)
{
//边遍历边打印,并存入栈中
while (p)
{
printf("%c ", p->data);
s.push(p);
p = p->left;
}
//当p为空时,说明根和左子树都遍历完了,进入右子树
if (!s.empty())
{
p = s.top();
s.pop();
p = p->right;
}
}
}
中序遍历
从根节点开始不断向左孩子遍历并入栈,直到为空,只要没有左孩子就出栈,在出栈的同时就打印节点数据,此时在判断出栈节点是否有右孩子,如果有右孩子重复上述操作继续向左孩子遍历,如果没有就出栈,重复上述操作判断有无右孩子,直到栈为空就退出遍历。
void InOrder(treenode* root)
{
//空树
if (root == NULL)
return;
//树非空
treenode* p = root;
stack<treenode *> s;
while (!s.empty() || p)
{
//一直遍历到左子树最下边,边遍历边保存根节点到栈中
while (p)
{
s.push(p);
p = p->left;
}
//当p为空时,说明已经到达左子树最下边,这时需要出栈了
if (!s.empty())
{
p = s.top();
s.pop();
printf("%c ", p->data);
//进入右子树
p = p->right;
}
}
}
后序遍历
后续在理解上较为难,用两个栈s1,s2更为直观,便于理解。
首先将根节点放入s2,再将其左右孩子放入s1中,一定要先放入左孩子,再放入右孩子,此时在获取s1栈顶节点并出栈,判断其是否有左右孩子,只要有孩子就将该节点入栈s2,并将该节点左右孩子放入s1中;如果该节点无左右孩子那么直接出栈s2并入栈s1,重复上述操作直到s1为空,在将s2从栈顶打印到栈底便是后续遍历
void PostOrder(treenode *root)
{
stack<treenode *>s1, s2;
treenode *cur=root;
s1.push(cur);//入栈根节点
while (!s1.empty())
{
cur = s1.top();
//出栈s1入栈s2
s1.pop();
s2.push(cur);
//判断是否有左右孩子,有则入栈s1
if (cur->left)
s1.push(cur->left);
if (cur->right)
s1.push(cur->right);
}
while (!s2.empty())
{
printf("%c ", s2.top()->data);//打印s2
s2.pop();
}
}
层序遍历
层序遍历需要用到队列,先入队根节点,在出队,将其左右孩子入队,依次出队入队操作,只要该节点有孩子就入队,再出队的同时打印节点数据
void sequence(treenode *root)
{
deque<treenode *>q;
treenode *cur = root;
q.push_back(cur);//根节点入队
while (!q.empty())
{
cur = q.front();//获取队头
q.pop_front();
printf("%c ", cur->data);
//孩子入队
if (cur->left)
q.push_back(cur->left);
if (cur->right)
q.push_back(cur->right);
}
}