非递归先序遍历:
步骤一:将二叉树根结点作为当前结点。
步骤二:当前结点非空,则先访问该结点,并入栈,同时将其左孩子结点作为当前结点;重复步骤,直到当前结点为空。
步骤三:如果栈非空,弹出栈顶结点,并将当前结点的右孩子结点作为当前结点。
步骤四:重复执行步骤二、三,直到栈为空且当前结点为空为止。
void PreOrderUnrec(Binary root)
{
//创建并初始化一个栈
Sqstack s;
StackInit(s);
p = root;
while (p != NULL || !StackEmpty(s))
{
//当结点不为空时,打印该结点元素,并入栈,同时将其左孩子作为当前结点
while (p != NULL)
{
print(p->data);
push(s, p);
p = p->left;
}
//当栈不为空时,弹出栈顶元素,并将其右孩子作为当前结点
if (!StackEmpty(s))
{
p = pop(s);
p = p->right;
}
}
}
非递归中序遍历:
步骤一:将二叉树根结点作为当前结点。
步骤二:当前结点非空,则将该结点入栈,同时将其左孩子结点作为当前结点;重复步骤,直到当前结点为空。
步骤三:如果栈非空,弹出栈顶结点并访问当前结点,并将当前结点的右孩子结点作为当前结点。
步骤四:重复执行步骤二、三,直到栈为空且当前结点为空为止。
void PreOrderUnrec(Binary root)
{
//创建并初始化一个栈
Sqstack s;
StackInit(s);
p = root;
while (p != NULL || !StackEmpty(s))
{
//当结点不为空时,并入栈,同时将其左孩子作为当前结点
while (p != NULL)
{
push(s, p);
p = p->left;
}
//当栈不为空时,弹出栈顶元素并打印该结点元素,将其右孩子作为当前结点
if (!StackEmpty(s))
{
p = pop(s);
print(p->data);
p = p->right;
}
}
}
非递归的后序遍历:
后序遍历时最后输出父亲结点,应先把右左孩子结点入栈,在父亲结点出栈时判断右左孩子是否遍历过(是否执行过入栈),所以要有一个标记来判断孩子是否便利过,于是就定义flag表示标志位。
//flag表示标志位,0表示左右孩子没有遍历,2表示左右孩子遍历完
typedef struct stackTreeNode
{
BinaryTree treenode;
int flag;
}*pSTree;
int LastOrder(BinaryTree root)
{
stack<pSTree>stackTree;
pSTree sTree = (pSTree)malloc(sizeof(struct stackTreeNode));
sTree->treenode = root;
sTree->flag = 0;
stackTree.push(sTree);
while (!stackTree.empty())
{
//栈顶结点作为当前结点
psTree tmptree = stackTree.top();
//如果当前结点的flag等于2时,打印该结点并弹出结点
if (tmptree->flag == 2)
{
cout << tmptree->treeNode->data << " ";
stackTree.pop();
}
//如果当前结点存在右孩子结点,将该右孩子结点作为当前结点,并入栈
if (tmptree->treeNode->right)
{
pSTree sTree = (pSTree)malloc(sizeof(struct stackTreeNode));
sTree->treeNode = tmptree->treenode->right;
sTree->flag = 0;
stackTree.push(sTree);
}
//当前结点flag加一
++tmptree->flag;
//如果当前结点存在左孩子,将该左孩子结点作为当前结点,并入栈
if(tmptree->treeNode->left)
{
pSTree sTree = (pSTree)malloc(sizeof(struct stackTreeNode));
sTree->treeNode = tmptree->treeNode->left;
sTree->flag = 0;
stackTree.push(sTree);
}
//当前结点flag加一
++tmptree->flag;
}
return 1;
}