一、前序遍历。比较简单。
- 如果根非空,进栈;
- 如果栈非空,访问栈顶元素,栈顶元素为p,出栈;
- 如果p的右孩非空,右孩进栈;
- 如果p的左孩非空,左孩进栈;
- 循环2,3,4。
源码:
void preOrderNoRecursion(BinaryTreeNode* root){
stack<BinaryTreeNode*> visitStack;
if(root!=NULL)
visitStack.push(root);
while(!visitStack.empty()){
BinaryTreeNode* top = visitStack.top();
visitStack.pop();
cout<<top->val<<" ";
if(top->right != NULL)
visitStack.push(top->right);
if(top->left != NULL)
visitStack.push(top->left);
}
}
二、中序遍历。思路: 若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;直到P为NULL并且栈为空则遍历结束;若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;直到P为NULL并且栈为空则遍历结束。
- 考察指针v指向根,非空,则进栈;
- 如果v的左孩非空,左孩进栈,直到左孩为空;
- 访问栈顶元素,栈顶元素为p,p出栈;
- 如果p右孩非空,v指向p的右孩。
- 循环1, 2,3,4。
源码:
void inOrderNoRecursion(BinaryTreeNode* root){
BinaryTreeNode* curVisit = root;
stack<BinaryTreeNode *> noVisit;
while(curVisit!=NULL || !noVisit.empty()){
while(curVisit!=NULL){
noVisit.push(curVisit);
curVisit = curVisit->left;
}
if(!noVisit.empty()){
BinaryTreeNode* top = noVisit.top();
noVisit.pop();
cout<<top->val<<" ";
curVisit = top->right;
}
}
}
三、后序遍历。算法思想:因为后序遍历是左右根。当用栈来存储节点,必须分清楚返回根节点时,是从左子树返回,还是从右子树返回的。所以使用一个辅助指针来指向起最近访问过的节点。也可以在节点中增加一个标志域,记录是否已被访问过(因为需要更改二叉树的数据结构,此处不用)。还有双栈法。
代码如下:
void postOrderNoRecursion(BinaryTreeNode* root){
BinaryTreeNode *curVisit=root, *haveVisit=NULL;
stack<BinaryTreeNode *> noVisit;
while(curVisit!=NULL || !noVisit.empty()){
while(curVisit!=NULL){
noVisit.push(curVisit);
curVisit = curVisit->left;
}
BinaryTreeNode* top = noVisit.top();
if(top->right==NULL || top->right==haveVisit){
cout<<top->val<<" ";
noVisit.pop();
haveVisit = top;
}else{
curVisit = top->right;
}
}
}
双栈法代码如下:
void postOrderNoRecursionTwoStack(BinaryTreeNode *root){
stack<BinaryTreeNode *> stack1, stack2;
BinaryTreeNode* curVisit=root;
if(curVisit!=NULL)
stack1.push(curVisit);
while(!stack1.empty()){
curVisit = stack1.top();
stack1.pop();
stack2.push(curVisit);
if(curVisit->left!=NULL)
stack1.push(curVisit->left);
if(curVisit->right != NULL)
stack1.push(curVisit->right);
}
while(!stack2.empty()){
curVisit = stack2.top();
cout<<curVisit->val<<" ";
stack2.pop();
}
}
四、整个源代码,包括递归。
#include <iostream>
#include <stack>
using namespace std;
struct BinaryTreeNode{
int val;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BinaryTreeNode(int val):val(val), left(NULL), right(NULL) {}
};
//前序遍历递归
void preOrderRecursion(BinaryTreeNode* root){
if(root!=NULL)
cout << root->val <<" ";
if(root->left != NULL)
preOrderRecursion(root->left);
if(root->right != NULL)
preOrderRecursion(root->right);
}
//前序遍历非递归
void preOrderNoRecursion(BinaryTreeNode* root){
stack<BinaryTreeNode*> visitStack;
if(root!=NULL)
visitStack.push(root);
while(!visitStack.empty()){
BinaryTreeNode* top = visitStack.top();
visitStack.pop();
cout<<top->val<<" ";
if(top->right != NULL)
visitStack.push(top->right);
if(top->left != NULL)
visitStack.push(top->left);
}
}
//中序遍历递归
void inOrderRecursion(BinaryTreeNode* root){
if(root==NULL)
return ;
if(root->left!=NULL)
inOrderRecursion(root->left);
cout<<root->val<<" ";
if(root->right!=NULL)
inOrderRecursion(root->right);
}
//中序遍历非递归
void inOrderNoRecursion(BinaryTreeNode* root){
BinaryTreeNode* curVisit = root;
stack<BinaryTreeNode *> noVisit;
while(curVisit!=NULL || !noVisit.empty()){
while(curVisit!=NULL){
noVisit.push(curVisit);
curVisit = curVisit->left;
}
if(!noVisit.empty()){
BinaryTreeNode* top = noVisit.top();
noVisit.pop();
cout<<top->val<<" ";
curVisit = top->right;
}
}
}
//后序遍历递归
void postOrderRecursion(BinaryTreeNode* root){
if(root==NULL)
return ;
if(root->left != NULL )
postOrderRecursion(root->left);
if(root->right != NULL)
postOrderRecursion(root->right);
cout<<root->val<<" ";
}
//后序遍历非递归
void postOrderNoRecursion(BinaryTreeNode* root){
BinaryTreeNode *curVisit=root, *haveVisit=NULL;
stack<BinaryTreeNode *> noVisit;
while(curVisit!=NULL || !noVisit.empty()){
while(curVisit!=NULL){
noVisit.push(curVisit);
curVisit = curVisit->left;
}
BinaryTreeNode* top = noVisit.top();
if(top->right==NULL || top->right==haveVisit){
cout<<top->val<<" ";
noVisit.pop();
haveVisit = top;
}else{
curVisit = top->right;
}
}
}
//后序遍历非递归,双栈法
void postOrderNoRecursionTwoStack(BinaryTreeNode *root){
stack<BinaryTreeNode *> stack1, stack2;
BinaryTreeNode* curVisit=root;
if(curVisit!=NULL)
stack1.push(curVisit);
while(!stack1.empty()){
curVisit = stack1.top();
stack1.pop();
stack2.push(curVisit);
if(curVisit->left!=NULL)
stack1.push(curVisit->left);
if(curVisit->right != NULL)
stack1.push(curVisit->right);
}
while(!stack2.empty()){
curVisit = stack2.top();
cout<<curVisit->val<<" ";
stack2.pop();
}
}
int main(){
BinaryTreeNode *node1 = new BinaryTreeNode(5);
BinaryTreeNode *node2 = new BinaryTreeNode(6);
BinaryTreeNode *node3 = new BinaryTreeNode(7);
BinaryTreeNode *node4 = new BinaryTreeNode(8);
node1->right = node2;
node2->right = node3;
node3->left = node4;
preOrderRecursion(node1);
cout<< endl;
preOrderNoRecursion(node1);
cout<<endl;
inOrderRecursion(node1);
cout<<endl;
inOrderNoRecursion(node1);
cout<<endl;
postOrderRecursion(node1);
cout<<endl;
postOrderNoRecursion(node1);
cout<<endl;
postOrderNoRecursionTwoStack(node1);
return 0;
}