二叉树的遍历(递归、非递归)

来源:互联网 发布:中国最帅的程序员 编辑:程序博客网 时间:2024/06/07 01:59

//完整代码,可直接运行

//其中包括二叉树的前序、中序、后序遍历,以及非递归的前序、中序、后序和层序遍历


//二叉树的遍历

#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>


using namespace std;


#define ERROR 0
#define TURE 1


typedef char DataType;
typedef int Status;


typedef struct BiTNode
{
DataType data;
struct BiTNode *rchild,*lchild;
}BiTNode,*BiTree;


//前序遍历
void PreOrder(BiTree T)
{
if(T!=NULL)
{
printf("%c ",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}


//中序遍历
void InOrder(BiTree T)
{
if(T!=NULL)
{
PreOrder(T->lchild);
printf("%c ",T->data);
PreOrder(T->rchild);
}
}


//后序遍历
void PostOrder(BiTree T)
{
if(T!=NULL)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%c ",T->data);
}
}



//构造二叉树
void CreateBiTree(BiTree *T)
{
DataType ch;
ch=getchar();
if(ch=='*')
*T=NULL;
else
{
*T=(BiTree)malloc(sizeof(BiTNode));
if(!*T)
return;
(*T)->data=ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}


//非递归 前序遍历
//根节点入栈,遍历左子树,返回时,栈顶元素是上一步根节点,遍历右子树
void PreOrder2(BiTree T)
{
stack<BiTree> stack;
BiTree p=T;
while(p || !stack.empty())
{
if(p!=NULL)
{
stack.push(p);
printf("%c ",p->data);
p=p->lchild;
}
else
{
p=stack.top();
stack.pop();
p=p->rchild;
}
}
}


//非递归 中序遍历
//遍历完左子树后再出桟输出
void InOrder2(BiTree T)
{
stack<BiTree> stack;
BiTree p=T;
while(p || !stack.empty())
{
if(p!=NULL)
{
stack.push(p);
p=p->lchild;
}
else
{
p=stack.top();
printf("%c ",p->data);
stack.pop();
p=p->rchild;
}
}

}


//非递归 后序遍历
//设置标志位'Y' 'N',作为当前节点是否是遍历的最终节点,是则打印,不是则继续遍历,并将当前节点入栈
//若遍历到头,打印节点并出桟,将上一节点出桟,标志位改为'N'
//啊哈哈,只有我看得懂吧
typedef struct BiTNodePost
{
BiTree biTree;
char tag;
}BiTNodePost,*BiTreePost;


void PostOrder2(BiTree T)
{
stack<BiTreePost> stack;
BiTree p=T;
BiTreePost BT;
while(p || !stack.empty())
{
while(p!=NULL)
{
BT=(BiTreePost)malloc(sizeof(BiTNodePost));
BT->biTree=p;
BT->tag='Y';
stack.push(BT);
p=p->lchild;
}
while(!stack.empty() && (stack.top())->tag=='N')
{
BT=stack.top();
stack.pop();
printf("%c ",BT->biTree->data);
}
if(!stack.empty())
{
BT=stack.top();
BT->tag='N';
p=BT->biTree;
p=p->rchild;
}
}

}


//层序遍历
//根节点入队,然后根节点的左子树、右子树入队,左子树出队,左子树的左子树、右子树入队,右子树出队,
//右子树的左子树右子树出队。。。
void LeverOrder(BiTree T)
{
BiTree p=T;
queue<BiTree> queue;
queue.push(p);
while(!queue.empty())
{
p=queue.front();
printf("%c ",p->data);
queue.pop();
if(p->lchild!=NULL)
queue.push(p->lchild);
if(p->rchild!=NULL)
queue.push(p->rchild);
}
}


//主函数
void main()
{
BiTree T;
printf("请输入你要建立的二叉树:");
CreateBiTree(&T);


printf("    前序遍历:   ");
PreOrder(T);
printf("\n");


printf("非递归 前序遍历:");
PreOrder2(T);
printf("\n \n");


printf("    中序遍历:   ");
InOrder(T);
printf("\n");


printf("非递归 中序遍历:");
InOrder2(T);
printf("\n \n");


printf("    后序遍历:   ");
PostOrder(T);
printf("\n");


printf("非递归 后序遍历:");
PostOrder2(T);
printf("\n \n");


printf("    层序遍历:   ");
LeverOrder(T);
printf("\n");

}


以上是最基本的代码,是看《大话数据结构》时根据书上代码编写的,适合最最基础的人看,有问题可以评论,同是菜鸟,我们一起讨论嘛~

1 0