一,前序遍历非递归:
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
void preOrder2(node *root) //非递归前序遍历
{
stack<node*> s;
node *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)//向左遍历直到叶子
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
cout<<endl;
}
二,中序遍历非递归
根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
void inOrder2(node *root) //非递归中序遍历
{
stack<node*> s;
node *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)//记录访问过的根节点
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
cout<<p->data<<" "; //访问栈顶
s.pop();
p=p->rchild; //将当前访问的元素的右孩子入栈
}
}
}
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void postOrder3(node *root) //非递归后序遍历
{
stack<node*> s;
node *cur; //当前结点
node *pre=NULL; //前一次访问的结点
s.push(root);
while(!s.empty())
{
cur=s.top();
if((cur->lchild==NULL&&cur->rchild==NULL)||
(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->rchild!=NULL)
s.push(cur->rchild);
if(cur->lchild!=NULL)
s.push(cur->lchild);
}
}
}
综合程序附录
#include "stdio.h"
#include "stdlib.h"
#include "stack.h"
int count;//统计叶子节点个数
struct node
{
int data;//二叉树的节点值
node *lchild,*rchild;//左右孩子节点
};
/*不知道为什么 创建的时候需要返回值才 创建有效*/
node *createTree()
{
node *root;
int data;
printf("input data:");
scanf("%d",&data);
//printf("output data:%d\n",data);
if(data==0)
root=NULL;
else/*根左右 前序建立二叉树*/
{
root=(node*)malloc(sizeof(node));
root->data=data;
root->lchild=createTree();
root->rchild=createTree();
}
return root;
}
void preOrder(node *root)
{
if(root==NULL)
return;
else//不是空
{
printf("%d\n",root->data);
preOrder(root->lchild);
preOrder(root->rchild);
}
}
void inOrder(node *root)
{
if(root==NULL)
return;
else//不是空
{
inOrder(root->lchild);
printf("%d\n",root->data);
inOrder(root->rchild);
}
}
void postOrder(node *root)
{
if(root==NULL)
return;
else//不是空
{
postOrder(root->lchild);
postOrder(root->rchild);
printf("%d\n",root->data);
}
}
void CountLeaves(node *root)
{
if(root==NULL)
return;
else//不是空
{
if(root->lchild==NULL&&root->rchild==NULL)
count++;
CountLeaves(root->lchild);
CountLeaves(root->rchild);
}
}
int deepLength(node *root)
{
int deep1,deep2;
if(root==NULL)
return 0;
else
{
deep1=deepLength(root->lchild);
deep2=deepLength(root->rchild);
if(deep1>deep2)
return deep1+1;//这个地方一定是返回+1
else
return deep2+1;
}
}
void CountNodes(node *root)
{
if(root==NULL)
return;
else//不是空
{
count++;
CountNodes(root->lchild);
CountNodes(root->rchild);
}
}
void exchange(node *root)
{
if(root==NULL)
return;
else
{
exchange(root->lchild);
exchange(root->rchild);
node *temp=root->lchild;
root->lchild=root->rchild;
root->rchild=temp;
}
}
void search(node *root,int x)
{
if(root==NULL)
return ;
else
{
if(root->data==x)
{
count++;
printf("has\n");
}
search(root->lchild,x);
search(root->rchild,x);
}
}
void preOrder2(node *root) //非递归前序遍历
{
stack<node*> s;
node *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)//向左遍历 直到叶子
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
cout<<endl;
}
void inOrder2(node *root) //非递归中序遍历
{
stack<node*> s;
node *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->rchild;
}
}
}
void postOrder3(node *root) //非递归后序遍历
{
stack<node*> s;
node *cur; //当前结点
node *pre=NULL; //前一次访问的结点
s.push(root);
while(!s.empty())
{
cur=s.top();
if((cur->lchild==NULL&&cur->rchild==NULL)||
(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->rchild!=NULL)
s.push(cur->rchild);
if(cur->lchild!=NULL)
s.push(cur->lchild);
}
}
}
/*一定要记住直接输入1 2 3 0 0 0 0 建立的是 左二叉树 平衡的应该是 1 2 0 0 3 0 0*/
int main()
{
node *root;//=(node*)malloc(sizeof(node));//这里不要初始化了 因为建立的时候要初始化
printf(" Please select what you want do\n");
printf("----------------------------------------------\n");
printf(" 1.前序创建二叉树\n");
printf(" 2.递归前序遍历二叉树\n");
printf(" 3.递归中序遍历二叉树\n");
printf(" 4.递归后序遍历二叉树\n");
printf(" 5.求叶节点个数\n");
printf(" 6.求树的高度\n");
printf(" 7.求二叉树节点个数\n");
printf(" 8.交换左右子树\n");
printf(" 9.查找有无某个节点\n");
printf(" 10.非递归前序遍历二叉树\n");
printf(" 11.非递归前序遍历二叉树\n");
printf(" 12.非递归前序遍历二叉树\n");
printf(" 15.退出\n");
int i;
while(true)
{
scanf("%d",&i);
switch(i)
{
case 1: root=createTree();
printf("create tree is finished please select what you want do next:\n");break;
case 2: printf("Now outPut data in PreOrder:\n");
preOrder(root);
printf("output is over please select again\n");break;
case 3: printf("Now outPut data in inOrder:\n");
inOrder(root);
printf("output is over please select again\n");break;
case 4: printf("Now outPut data in postOrder:\n");
postOrder(root);
printf("output is over please select again\n");break;
case 5: count=0;
CountLeaves(root);
printf("The leaves's count is:%d\n",count);
printf("output is over please select again\n");break;//叶子节点的个数
case 6: int deep=deepLength(root);
printf("The tree's deepLength is:%d\n",deep);
printf("output is over please select again\n");break;
case 7: count=0;
CountNodes(root);
printf("The leaves's count is:%d\n",count);
printf("output is over\n");
break;//求二叉树节点个数
case 8: exchange(root);
break;
case 9: printf("please input what you want search\n");
int x;
scanf("%d",&x);
count=0;
search(root,x);
if(count!=0)
{
printf("The tree has this root\n");
printf("output is over please select again\n");
}
else
{
printf("The tree not has this root\n");
printf("output is over please select again\n");
}
break;
case 10: printf("Now outPut data in PreOrder:\n");
preOrder2(root);
printf("output is over please select again\n");break;
case 11: printf("Now outPut data in PreOrder:\n");
inOrder2(root);
printf("output is over please select again\n");break;
case 12: printf("Now outPut data in PreOrder:\n");
postOrder3(root);
printf("output is over please select again\n");break;
case 15: exit(0); break;//包含在stdlib.h当中
}
}
return 0;
}