二叉树递归遍历代码:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
//二叉树的链式存储结构
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void InitBiTree(BiTree &T){
BiTNode *t1=T;
t1->data=1;
BiTree t2=(BiTNode*)malloc(sizeof(BiTNode));
t2->data=2;
t1->lchild=t2;//根节点的左子树
BiTree t3=(BiTNode*)malloc(sizeof(BiTNode));
t3->data=3;
t1->rchild=t3;
BiTree t4=(BiTNode*)malloc(sizeof(BiTNode));
t4->data=4;
BiTree t5=(BiTNode*)malloc(sizeof(BiTNode));
t5->data=5;
t2->lchild=t4;
t2->rchild=t5;
BiTree t6=(BiTNode*)malloc(sizeof(BiTNode));
t6->data=6;
t3->lchild=t6;
t3->rchild=NULL;
//将叶子节点左右孩子指针置空
t4->lchild=NULL;
t4->rchild=NULL;
t5->lchild=NULL;
t5->rchild=NULL;
t6->lchild=NULL;
t6->rchild=NULL;
}
void visit(BiTree T) {
printf("%d ",T->data);
}
//前序遍历
void PreOrder(BiTree T){
if(T!=NULL){
visit(T);//根
PreOrder(T->lchild);//左
PreOrder(T->rchild);//右
}
}
//中序遍历
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
//后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
int main(){
BiTree t=(BiTNode*)malloc(sizeof(BiTNode));
InitBiTree(t);
printf("前序遍历为:");
PreOrder(t);
printf("\n");
printf("中序遍历为:");
InOrder(t);
printf("\n");
printf("后序遍历为:");
PostOrder(t);
printf("\n");
}
代码运行截图:
二叉树非递归遍历代码(借助栈来实现):
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
//二叉树的链式存储结构
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void InitBiTree(BiTree &T){
BiTNode *t1=T;
t1->data=1;
BiTree t2=(BiTNode*)malloc(sizeof(BiTNode));
t2->data=2;
t1->lchild=t2;//根节点的左子树
BiTree t3=(BiTNode*)malloc(sizeof(BiTNode));
t3->data=3;
t1->rchild=t3;
BiTree t4=(BiTNode*)malloc(sizeof(BiTNode));
t4->data=4;
BiTree t5=(BiTNode*)malloc(sizeof(BiTNode));
t5->data=5;
t2->lchild=t4;
t2->rchild=t5;
BiTree t6=(BiTNode*)malloc(sizeof(BiTNode));
t6->data=6;
t3->lchild=t6;
t3->rchild=NULL;
//将叶子节点左右孩子指针置空
t4->lchild=NULL;
t4->rchild=NULL;
t5->lchild=NULL;
t5->rchild=NULL;
t6->lchild=NULL;
t6->rchild=NULL;
}
void visit(BiTree T) {
printf("%d ",T->data);
}
//先序遍历非递归
void PreOrdernorecursion(BiTree T){
if(T!=NULL){
BiTree stack[MaxSize];//借助一个存放节点地址的栈
int top=-1;
BiTree p;//遍历指针
stack[++top]=T;
while(top!=-1){
p=stack[top--];
visit(p);
if(p->rchild!=NULL){
stack[++top]=p->rchild;//先将右孩子入栈,这样才能让左孩子先出栈
}
if(p->lchild!=NULL){
stack[++top]=p->lchild;
}
}
}
}
//中序遍历非递归
void InOrdernorecursion(BiTree T){
if(T!=NULL){
BiTree stack[MaxSize];//借助一个存放节点地址的栈
int top=-1;
BiTree p=T;//遍历指针
//此处写两个判断条件是为了栈被弹空而存在右孩子的情况下能继续访问
//因为中序遍历是左根右,所以先是左到底,然后再依次弹出栈, 左到底可以将根节点也入栈,
//但右孩子没能入栈,所以需要两个条件
while(top!=-1||p!=NULL){//此处的判断条件为只要栈不空或者p指针不空
while(p!=NULL){//先左到底
stack[++top]=p;
p=p->lchild;
}
if(top!=-1){//如果栈不空则可以出栈
p=stack[top--];//出栈
visit(p);
p=p->rchild;//指向其右孩子
}
}
}
}
//后序遍历非递归
//后序遍历为逆后序逆置顺序
//逆后序(根右左)和先序(根左右)遍历方式相似
void PostOrdernorecursion(BiTree T){
if(T!=NULL){
BiTree stack[MaxSize];//借助一个存放节点地址的栈
BiTree stack1[MaxSize];//借助一个存放节逆后序的栈
int top=-1;
int top1=-1;
BiTree p;//遍历指针
stack[++top]=T;
//和先序遍历两处不同
while(top!=-1){
p=stack[top--];
stack1[++top1]=p;//一为先序遍历为在此处访问根节点, 而在此处为入栈2
if(p->lchild!=NULL){
stack[++top]=p->lchild;//二为先入栈左孩子才能后出
}
if(p->rchild!=NULL){
stack[++top]=p->rchild;
}
}
while(top1!=-1){
p=stack1[top1--];
visit(p);
}
}
}
int main(){
BiTree t=(BiTNode*)malloc(sizeof(BiTNode));
InitBiTree(t);
printf("前序遍历为:");
PreOrdernorecursion(t);
printf("\n");
printf("中序遍历为:");
InOrdernorecursion(t);
printf("\n");
printf("后序遍历为:");
PostOrdernorecursion(t);
printf("\n");
}
代码运行截图:
层次遍历代码(利用队列):
void level(BiTree T){
if(T!=NULL){
int front=0;
int rear=0;
BiTree queue[MaxSize];
BiTree p;
p=T;
rear=(rear+1)%MaxSize;
queue[rear]=p;
while(rear!=front){
front=(front+1)%MaxSize;
p=queue[front];
visit(p);
if(p->lchild!=NULL){
rear=(rear+1)%MaxSize;
queue[rear]=p->lchild;
}
if(p->rchild!=NULL){
rear=(rear+1)%MaxSize;
queue[rear]=p->rchild;
}
}
}
}
代码运行截图: