二叉树的定义:
二叉树是由n(n>=0)个结点的有限集合构成,此集合或者为空集,或者由一个根结点及两棵互不相交的左右子树组成,并且左右子树都是二叉树.
递归定义:叉树可以是空集合,根可以有空的左子树或空的右子树。二叉树不是树的特殊情况,它们是两个概念。
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
二叉树的遍历
原表达式:a+b*(c-d)-e/f
先序遍历:-+a*b-cd/ef
中序遍历:a+b*c-d-e/f
后序遍历:abcd-*+ef/-
先序递归遍历过程
即先序遍历完成
void PreOrderTraverse(BiTree BT)
{
if(BT)
{
if(!(BT->data))
return;
printf("%c",BT->data);
PreOrderTraverse(BT->lchild);
PreOrderTraverse(BT->rchild);
}
}
中序遍历和后序遍历同上
层次非递归遍历
该树的层次递归遍历为:ABCDEGF
运用队列来存储树的结点首先A入队,输出A结点,然后队首结点A出队,将A的孩子结点B,C分别入队。访问队首结点B,输出并出队,将B的孩子结点D,E入队。访问队首结点C,输出并出队,C结点只有右孩子,将C的右孩子结点G入队。访问队首结点D,输出并出队,D没有孩子结点,不入队。访问队首结点E,输出并出队,将E的孩子结点F入队。访问队首结点G,输出并出队,G没有孩子结点,不入队。访问队首结点F,输出并出队,F没有孩子结点,不入队。此时队列为空,结束遍历。
void leverTraverse(BiTree BT)
{
Squeue Q;
BiTree pt=BT;
InitQueue(&Q);
EnQueue(&Q,pt);
while(!EmptyQueue(Q))
{
Dequeue(&Q,&pt);
printf("%c",pt->data);
if(pt->lchild)
EnQueue(&Q,pt->lchild);
if(pt->rchild)
EnQueue(&Q,pt->rchild);
}
}
完整代码:
// erchashu.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#define MAXSIZE 50
int max=0;
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct SQueue{
BiTree *base;
int front;
int rear;
}Squeue;
void InitBiTree(BiTree *BT)
{
*BT=NULL;
}
void PreCreatBiTree(BiTree *BT)
{
ElemType ch;
printf("输入数据:\n");
getchar();
ch=getchar();
if(ch=='#')
*BT=NULL;
else
{
*BT=(BiTree)malloc(sizeof(BiTNode));
(*BT)->data=ch;
PreCreatBiTree(&(*BT)->lchild);
PreCreatBiTree(&(*BT)->rchild);
}
}
void PreOrderTraverse(BiTree BT)
{
if(BT)
{
if(!(BT->data))
return;
printf("%c",BT->data);
PreOrderTraverse(BT->lchild);
PreOrderTraverse(BT->rchild);
}
}
void InOrderTraverse(BiTree BT)
{
if(BT)
{
if(!(BT->data))
return;
InOrderTraverse(BT->lchild);
printf("%c",BT->data);
InOrderTraverse(BT->rchild);
}
}
void PostOrderTraverse(BiTree BT)
{
if(BT)
{
if(!(BT->data))
return;
PostOrderTraverse(BT->lchild);
PostOrderTraverse(BT->rchild);
printf("%c",BT->data);
}
}
void InitQueue(Squeue *Q)
{
(*Q).base=(BiTree *)malloc(sizeof(BiTNode)*MAXSIZE);
(*Q).front=(*Q).rear=0;
}
void EnQueue(Squeue *Q,BiTree BT)
{
(*Q).base[(*Q).rear++]=BT;
}
int EmptyQueue(Squeue Q)
{
if(Q.front==Q.rear)
return 1;
return 0;
}
void Dequeue(Squeue *Q,BiTree *pt)
{
if((*Q).front==(*Q).rear)
return;
*pt=(*Q).base[(*Q).front];
(*Q).front=((*Q).front +1) % MAXSIZE;
}
void leverTraverse(BiTree BT)
{
Squeue Q;
BiTree pt=BT;
InitQueue(&Q);
EnQueue(&Q,pt);
while(!EmptyQueue(Q))
{
Dequeue(&Q,&pt);
printf("%c",pt->data);
if(pt->lchild)
EnQueue(&Q,pt->lchild);
if(pt->rchild)
EnQueue(&Q,pt->rchild);
}
}
void NRPreOrderTraverse(BiTree BT)
{
BiTree pt=BT,stack[MAXSIZE];
int top=0;
while(pt || top)
{
if(pt)
{
printf("%c",pt->data);
stack[top++]=pt;
pt=pt->lchild;
}
else
{
pt=stack[--top];
pt=pt->rchild;
}
}
}
int BiTreedepth(BiTree BT,int depth)
{
if(BT)
{
if(BT->lchild)
BiTreedepth(BT->lchild,depth+1);
if(BT->rchild)
BiTreedepth(BT->rchild,depth+1);
}
if(depth>max)
max=depth;
return depth;
}
int LeafNumber(BiTree BT)
{
if(!BT)
return 0;
else
{
if((!BT->lchild) && (!BT->rchild))
return 1;
else
return LeafNumber(BT->lchild)+LeafNumber(BT->rchild);
}
}
int singleBiTree(BiTree BT)
{
if(!BT)
return 0;
else
{
if(BT->lchild && !BT->rchild)
return singleBiTree(BT->lchild)+1;
else
{
if(!BT->lchild && BT->rchild)
return singleBiTree(BT->lchild)+1;
else
return singleBiTree(BT->lchild)+singleBiTree(BT->rchild);
}
}
}
int doubleBiTree(BiTree BT)
{
int book=0;
if(!BT)
return 0;
if(BT->lchild && BT->rchild)
book=1;
return book+doubleBiTree(BT->lchild)+doubleBiTree(BT->rchild);
}
void revoluteBiTree(BiTree *BT)
{
BiTree T;
if(!(*BT)->lchild && !(*BT)->rchild)
return;
else
{
T=(*BT)->lchild;
(*BT)->lchild=(*BT)->rchild;
(*BT)->rchild=T;
}
if((*BT)->lchild)
{
revoluteBiTree(&(*BT)->lchild);
}
if((*BT)->rchild)
{
revoluteBiTree(&(*BT)->rchild);
}
}
int main(int argc, char* argv[])
{
BiTree BT;
int tmp;
int flag=1,select;
InitBiTree(&BT);
while(flag)
{
printf("\n请选择:\n");
printf("0. 先序创建二叉树用#代表空结点\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("请输入要执行的操作:\n");
scanf("%d",&select);
switch(select)
{
case 0:
PreCreatBiTree(&BT);
break;
case 1:
printf("\n先序遍历为:\n");
PreOrderTraverse(BT);
break;
case 2:
printf("\n中序遍历为:\n");
InOrderTraverse(BT);
break;
case 3:
printf("\n后序遍历为:\n");
PostOrderTraverse(BT);
break;
case 4:
printf("\n层次非递归遍历为:\n");
leverTraverse(BT);
break;
case 5:
printf("\n先序非递归遍历为:\n");
NRPreOrderTraverse(BT);
break;
case 6:
printf("\n高度为: ");
BiTreedepth(BT,1);
printf("%d\n",max);
break;
case 7:
printf("\n叶结点数目为: ");
tmp=LeafNumber(BT);
printf("%d\n",tmp);
break;
case 8:
printf("\n单分支结点数目为: ");
tmp=singleBiTree(BT);
printf("%d\n",tmp);
break;
case 9:
printf("\n双分支结点数目为: ");
tmp=doubleBiTree(BT);
printf("%d\n",tmp);
break;
case 10:
printf("\n已交换二叉树\n");
revoluteBiTree(&BT);
break;
default:
flag=0;
printf("Press any key to exit!\n");
break;
}
}
printf("\n");
return 0;
}