二叉树的非递归遍历
二叉树的三种遍历方式也可以通过非递归的方法借助栈 来实现。
通过控制节点的出栈和入栈先后顺序来实现对树的不同方式的遍历。
非递归先根遍历二叉树
当栈不为空或者当前节点为不为空,执行操作:
从根节点开始,依次访问 树中最左端的节点并入栈,当节点为空停止入栈。
取栈顶元素为当前节点并出栈,如果当前节点有右子树,则遍历其右子树。
void PreorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
cout << pT->data << " " ;
pT = pT->left;
}
else
{
pT = getTop(S);
Pop(S);
pT = pT->right;
}
}
cout << endl;
delete S;
}
非递归中根遍历二叉树
当栈不为空或者当前节点为不为空,执行操作:
同样地,先依次将根节点及其左子树最左端的节点入栈,但不进行访问。当节点为空,则停止入栈。
访问 栈顶元素作为当前节点并出栈,如果当前节点有右子树,则遍历访问其右子树。
void InorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
pT = pT->left;
}
else
{
pT = getTop(S);
Pop(S); cout << pT->data << " " ;
pT = pT->right;
}
}
cout << endl;
delete S;
}
非递归后根遍历二叉树
非递归后根遍历相比前两个有点麻烦,需要引入一个中间变量标记已经访问节点。
当栈不为空或者当前节点为不为空,执行操作:
依次将根节点及其左子树的左端节点入栈,但不进行访问,当节点为空,停止入栈。
取栈顶元素作为当前节点,如果当前节点的右孩子(右子树)不为空且其右孩子不是上一次访问的节点。则当前节点变为其右子树,遍历其右子树。如果当前节点的右孩子为空或者其右孩子已经被访问,则访问 当前节点,标记当前节点为已访问节点,出栈。将当前节点置为空(此时右孩子访问过了),继续取栈顶元素(为了访问根节点)。
void PostorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
TreeNode* qT = nullptr ;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
pT = pT->left;
}
else
{
pT = getTop(S);
if (pT->right && pT->right != qT)
{
pT = pT->right;
}
else
{
Pop(S);
cout << pT->data << " " ;
qT = pT;
pT = nullptr ;
}
}
}
cout << endl;
delete S;
}
附总的代码实现
#include<iostream>
using namespace std ;
typedef int ElemType;
typedef struct _TreeNode {
ElemType data;
struct _TreeNode* left;
struct _TreeNode* right;
}TreeNode, *SearchBTree;
typedef SearchBTree StackElemType;
typedef struct StackNode {
SearchBTree data;
StackNode *next;
}*Stack;
void initStack(Stack St)
{
St->next = nullptr ;
}
int isEmpty(Stack St)
{
return St->next == nullptr ;
}
void Push(Stack St, SearchBTree x)
{
StackNode* q = new StackNode;
q->data = x;
q->next = St->next;
St->next = q;
}
void Pop(Stack St)
{
StackNode* p = St->next;
St->next = p->next;
delete p;
}
SearchBTree getTop(Stack St)
{
return St->next->data;
}
SearchBTree EmptyTree(SearchBTree T)
{
if (!T)
{
EmptyTree(T->left);
EmptyTree(T->right);
delete T;
}
return nullptr ;
}
void Insert(SearchBTree &T, ElemType x)
{
if (!T)
{
TreeNode* pT = new TreeNode;
pT->data = x;
pT->left = pT->right = nullptr ;
T = pT;
}
else
{
if (x < T->data)
Insert(T->left, x);
else if (x > T->data)
Insert(T->right, x);
}
}
void PreorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
cout << pT->data << " " ;
pT = pT->left;
}
else
{
pT = getTop(S);
Pop(S);
pT = pT->right;
}
}
cout << endl;
delete S;
}
void InorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
pT = pT->left;
}
else
{
pT = getTop(S);
Pop(S); cout << pT->data << " " ;
pT = pT->right;
}
}
cout << endl;
delete S;
}
void PostorderPrint(SearchBTree T)
{
if (T == nullptr )
{
cout << "Empty tree!" ;
exit (1 );
}
Stack S = new StackNode;
initStack(S);
TreeNode* pT = T;
TreeNode* qT = nullptr ;
while (pT || !isEmpty(S))
{
if (pT)
{
Push(S, pT);
pT = pT->left;
}
else
{
pT = getTop(S);
if (pT->right && pT->right != qT)
{
pT = pT->right;
}
else
{
Pop(S);
cout << pT->data << " " ;
qT = pT;
pT = nullptr ;
}
}
}
cout << endl;
delete S;
}
int main()
{
const ElemType rawdata[] = { 19 , 7 , 9 , 15 , 23 , 39 , 4 , 2 , 75 , 100 , 43 , 58 };
SearchBTree myTree = new TreeNode;
myTree = EmptyTree(myTree);
for (int i = 0 ;i < sizeof (rawdata) / sizeof (ElemType);i++)
{
Insert(myTree, rawdata[i]);
}
cout << "The inorder print of the tree is: \n" ;
InorderPrint(myTree);
cout << "The preorder print of the tree is: \n" ;
PreorderPrint(myTree);
cout << "The postorder print of the tree is: \n" ;
PostorderPrint(myTree);
delete myTree;
system("pause" );
return 0 ;
}
The preorder print of the tree is :
19 7 4 2 9 15 23 39 75 43 58 100
The inorder print of the tree is :
2 4 7 9 15 19 23 39 43 58 75 100
The postorder print of the tree is :
2 4 15 9 7 58 43 100 75 39 23 19