本博客的参考代码来自博主qq_41907471,介于单看代码不太好理解,我给每部分的代码的作用加了注释,从而便于大家理解。
//FrontSearch函数用于前序遍历二叉树。
void FrontSearch(Binarytree *Root)
{
if (Root == NULL)
return;//Root所含有的地址为空指针,说明其没有节点。
stack<Binarytree *>s;
s.push(Root);//将根节点压入栈。
while (!s.empty())
{
Binarytree *temp = s.top();
s.pop();
//写相关程序以进行你想进行的操作(及遍历完当前节点)。
if (temp->right != NULL)
s.push(temp->right);//栈顶节点存在右节点,则将该右节点入栈。
if (temp->left != NULL)
s.push(temp->left);//栈顶节点存在左节点,则将该左节点入栈。
}//在将子节点进行入栈时,由于要先遍历左节点,后遍历右节点,所以要先将右节点入栈,再将做节点入栈。
}
//MiddleSearch函数用于中序遍历二叉树。
void MiddleSearch(Binarytree *Root)
{
if (Root == NULL)
return;
stack<Binarytree *>s;
Binarytree *Node = Root;
while (!s.empty() || Node)
{
while (Node)
{
s.push(Node);
Node = Node->left;
}//从根节点开始,将其极左子节点入栈。
Node = s.top();//从最后一个极左节点开始遍历(第二次运行到此处时弹出该极左节点的父节点)
s.pop();
//写相关程序以进行你想进行的操作(及遍历完当前节点)。
Node = Node->right;
//程序第一次运行到此处时Node为空指针,因为刚刚弹出的栈顶节点是最后一个极左节点,其没有子节点,
//程序第二次运行到此处时最后极左节点的父节点已经遍历完毕,Node赋值为其有子节点的地址。
}
}
//BackSearch函数用于后序遍历二叉树。
void BackSearch(Binarytree *Root)
{
if (Root == NULL)
return;
int sign[20];
stack<Binarytree *>s;
Binarytree *Node = Root;
while (Node)
{
sign[s.size()] = 1;//s.size()为返回当前栈(STL容器)中元素的个数。
s.push(Node);
Node = Node->left;
}//与中序遍历相同,,从根节点开始,将其极左子节点入栈。
while (!s.empty())
{
Node = s.top();//程序第二次运行到这里时Node为最后一个极左节点的父节点,但不能遍历其,而应
//遍历其的右子节点。
while (Node->right&&sign[s.size()] == 1)//Node->right判断当前Node是否有右子节点,sign[s.size]==1
//判断其右子节点是否已经遍历过。
{
Node = Node->right;//能入次循环,说明其右子节点存在且没有被遍历过,故将Node赋值为
//该右子节点的地址。
sign[s.size()] = 0;//表示该右子节点已经被遍历。
while(Node)
{
s.push(Node);
sign[s.size()] = 1;
Node = Node->left;
}//将该右子节点的所有左子孙节点入栈。
Node = s.top();
}
//写相关程序以进行你想进行的操作(即遍历完当前节点)。
s.pop();
}
}//后序遍历中的sign[s,size()]通过当前栈中元素的个数的位置进行0或1的赋值,当遍历完一个右子节点后,
//会有元素从栈顶弹出,之后在sign数组相对应的位置的值如果为0,则表示当前判断的右子节点已经被遍历过
//且不再遍历,并且此时的Node为该右子节点的父节点的地址,从而遍历其;如果为1,则说明该右子节点没有
//被遍历,从而对其进行左子孙节点的判断与压栈以及自身的遍历。