您的位置:首页 > 其它

二叉树的遍历

2012-10-25 10:14 309 查看
二叉树的非递归遍历

#include"stdio.h"
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
//数据结构
typedef struct node
{
int value;
struct node *lchild;
struct node *rchild;
}BiNode;
typedef BiNode* BiTree;

typedef struct BTNode{
BiNode * btnode;
bool isFrist;
}BTNode;
//初始化
void InitBiTree(BiTree *T)
{
*T = NULL;
}
//创建
void CreateBiTree(BiTree *T)
{
int value;
printf("输入值:\n");
scanf("%d",&value);
if(value!= 0)
{
*T = (BiNode *)malloc(sizeof(BiNode));
(*T)->value = value;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
CreateBiTree(&((*T)->lchild));
CreateBiTree(&((*T)->rchild));
}
else
{
*T = NULL;
return;
}
}
//按层创建
void CreateBiTreeByLevel(BiTree *T,int *Array,int i,int len)
{
if((Array[i] == 0)|| i > len)return;
*T = (BiNode *)malloc(sizeof(BiNode));
if(!(*T))exit(0);
(*T) ->value = Array[i];
(*T)->lchild = NULL;
(*T)->rchild = NULL;
CreateBiTreeByLevel(&(*T)->lchild,Array,2*i,len);
CreateBiTreeByLevel(&(*T)->rchild,Array,2*i+1,len);
}
void display(BiTree *t)        //显示树形结构
{
if(*t!=NULL)
{
cout<<(*t)->value;
if((*t)->lchild!=NULL)
{
cout<<'(';
display(&(*t)->lchild);
}
if((*t)->rchild!=NULL)
{
cout<<',';
display(&(*t)->rchild);
cout<<')';
}
}
}
//----------------深度遍历二叉树-------递归的方法-------
//前序遍历
void PreOrderTraverse(BiTree *t)
{
if(!(*t))return;
printf("%d",(*t)->value);
PreOrderTraverse(&((*t)->lchild));
PreOrderTraverse(&((*t)->rchild));
}
// 后序遍历
void PostOrderTraverse(BiTree *t)
{
if(!(*t))return;
PostOrderTraverse(&((*t)->lchild));
PostOrderTraverse(&((*t)->rchild));
printf("%d",(*t)->value);
}

//中序遍历
void InOrderTraverse(BiTree *t)
{
if(!(*t))return;
InOrderTraverse(&(*t)->lchild);
printf("%d",(*t)->value);
InOrderTraverse(&(*t)->rchild);
}
//-------------------深度遍历二叉树---非递归方法---------------------------
//非递归前序遍历
/************************************************************************/
/* 1)访问节点p,将节点p入栈*/
/* 2)p左孩子不为空,则一直入栈,当p的左孩子为空时,出栈*/
/* 3)直到p为空或者栈s为空,遍历结束*/
/*前序遍历根左右,入栈时访问为谦虚,中序遍历时,左根右,出栈时访问*/
/************************************************************************/
void PreOrderTraverse1(BiTree *t)
{
stack <BiTree> s;
BiNode *p = *t;
while(p!=NULL||!s.empty())
{
while(p)
{
printf("%d",p->value);
s.push(p);
p = p->lchild;
}
if(!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}

//非递归中序遍历
void InOrderTraverse1(BiTree *t)
{
stack<BiTree> s;
BiNode *p = *t;
while(p!=NULL || !s.empty())
{
while(p)
{
s.push(p);
p = p->lchild;
}
if(!s.empty())
{
p = s.top();
printf("%d",p->value);
s.pop();
p = p->rchild;
}
}
}

//后续非递归遍历
/*
第一种思路:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,
此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同
的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现
在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
*/
void PostOrderTraverse1(BiTree *t)
{
stack<BTNode*> s;
BiNode *p = *t;
BTNode *temp;
while(p!=NULL||!s.empty())
{
while(p)
{
BTNode *btn = (BTNode *)malloc(sizeof(BTNode));
btn->btnode = p;
btn->isFrist = true;
s.push(btn);
p = p->lchild;
}
if(!s.empty())
{
temp = s.top();
s.pop();
if(temp->isFrist)
{
s.push(temp);
temp->isFrist = false;
p = temp->btnode->rchild;
}
else
{
printf("%d",temp->btnode->value);
p = NULL;
}

}
}
}
/*
第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右
孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次
入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点
前面被访问。
*/
void PostOrderTraverse2(BiTree *t)
{
stack<BiNode*> s;
BiNode *pre = NULL;
BiNode *cur = NULL;
s.push(*t);
while(!s.empty())
{
cur = s.top();
if(((cur->lchild == NULL)&&(cur->rchild == NULL))||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
printf("%d",cur->value);//如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();                //由于入栈时根右左,pre指向其右或者左节点,
pre = cur;
}
else
{
if(cur->rchild!=NULL)s.push(cur->rchild);
if(cur->lchild!=NULL)s.push(cur->lchild);
}
}
}
//---------------------按照层序遍历二叉树,二叉树的广度遍历---------------------
void LevelOrderTranverse(BiTree *t)
{
queue<BiNode *> q;
BiNode * p = NULL;
if(*t)q.push(*t);
else return;

while(!q.empty())
{
p = q.front();
q.pop();
cout<<p->value<<"*";
if (p->lchild!=NULL)q.push(p->lchild);
if (p->rchild!=NULL)q.push(p->rchild);
}
}
int main()
{
BiTree T;
InitBiTree(&T);
int a[14] = {0,1,2,3,4,5,6,0,0,0,7,0,8,9};//从下标1开始,0标识没有节点
CreateBiTreeByLevel(&T,a,1,13);
display(&T);
/*printf("\n---------PreOrder---------------\n");
PreOrderTraverse(&T);
printf("\n--------------------------------\n");
PreOrderTraverse1(&T);
printf("\n---------InOrder-----------------\n");
InOrderTraverse(&T);
printf("\n------------------------\n");
InOrderTraverse1(&T);
printf("\n---------PostOrder---------------\n");
PostOrderTraverse(&T);
printf("\n---------------------------------\n");
PostOrderTraverse1(&T);
printf("\n---------------------------------\n");
PostOrderTraverse2(&T);*/
printf("\n------------lll---------------------\n");
LevelOrderTranverse(&T);
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: