本文主要介绍二叉树的相关基础操作,参考教材数据结构严慧敏版。
一.前期准备
(1)定义二叉树的存储结构
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"string.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
#define Max_ Tree_SIZE 20
#define StackInitSize 100
#define Maxsize 100
typedef void Status;
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef BiTree SElemType;
(2)栈结构的初始化及相关操作
typedef struct Stack{
SElemType *top;
SElemType *base;
int size;
}Stack;
bool EmptyStack(Stack S){
if(S.base==S.top)
return true;
return false;
}
Status Pop(Stack &S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
S.top--;
}
Status Push(Stack &S,SElemType e){
if(S.top-S.base>=99)return;
S.top++;
*(S.top)=e;
}
Status GetTop(Stack S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
}
Status InitStack(Stack &S){
S.base=S.top=(SElemType *)malloc(StackInitSize*sizeof(SElemType));
if(!S.base)
return;
S.size=StackInitSize;
}
(3)队列结构的初始化及相关操作
typedef struct{
SElemType data[Maxsize];
int front,rear;
}Queue;
bool EmptyQueue(Queue &a){
if(a.front==a.rear)
return true;
return false;
}
void DeQueue(Queue &a,SElemType &b){//不要疑惑这种写法,这种写法没问题
a.front++;
b=a.data[a.front];
}
void EnQueue(Queue &a,SElemType &b){//EnterQueue
a.rear++;
a.data[a.rear]=b;
}
void InitQueue(Queue &a){
a.front=a.rear=-1;
}
(4)二叉树的函数声明及相关操作
Status InitBiTree(BiTree &BT);
Status CreateBiTree(BiTree *BT);//先序递归创建二叉树
Status PreOrder(BiTree BT);
Status InOrder(BiTree BT);
Status PostOrder(BiTree BT);
int TreeDepth(BiTree BT);
int TreeWidth(BiTree BT,Queue &Q);//求宽度
Status NRPreOrder(BiTree BT,Stack &S);
Status NRInOrder(BiTree BT,Stack &S);
Status NRPostOrder(BiTree BT,Stack &S);
Status LevelOrder(BiTree BT,Queue &Q);
int Count0(BiTree BT);
int Count1(BiTree BT);
int Count2(BiTree BT);
int Count_two(BiTree BT,Stack &S);//求双分支结点数目 非递归算法
int Count_two2(BiTree BT,Stack &S);//这是求双分支结点数目 非递归算法 利用中序遍历
int Count_two3(BiTree BT,Stack &S);//利用后序非递归遍历二叉树 来求双分支结点数目
Status ChangeTree(BiTree BT);
void visit(BiTree a);
void visit(BiTree a){
printf("%c",a->data);
}
Status InitBiTree(BiTree &BT){
BT=(BiTNode*)malloc(sizeof(BiTNode));
BT=NULL;
}
二.相关常用的基础操作
1.构造二叉树
(1)输入先序序列构造二叉树
Status CreateBiTree(BiTree *BT){ //status <=> void
char c;
scanf(" %c", &c); // 注意这里的空格,可以读取空格后的字符
if (c == '#'){
*BT = NULL;
}
else{
*BT=(BiTree)malloc(sizeof(BiTNode)); // 这里应该分配的是BiTNode的大小,我假设BiTNode是一个包含左右子树指针和数据字段的结构体
printf("----\n");
(*BT)->data = c;
CreateBiTree(&((*BT)->lchild));
CreateBiTree(&((*BT)->rchild));
}
}
(2)输入广义表构造二叉树
void CreateTreeByList(BiTree &BT,Stack &S){
int flag=1;
char ch;
BiTree p,e;
BT=NULL;
scanf("%c",&ch);
while(ch!='#'){
switch(ch){
case'(':flag=1;Push(S,p);break;//遇到左括号让flag=1表示准备构建当前栈顶结点的左子树
case',':flag=0;break;//遇到右括号让flag=0表示准备构建当前栈顶的右子树
case')':Pop(S,p);break;
default: //对于A(B,C)
p=(BiTree)malloc(sizeof(BiTNode));//第二次是指向一处新的空间(左孩子),原来的A结点仍然在那里,第三次则指向右孩子
p->lchild=p->rchild=NULL;
p->data=ch;
if(BT==NULL) BT=p;
else{
GetTop(S,e);
if(flag){
e->lchild=p;
}
else{
e->rchild=p;
}
}
}
scanf("%c",&ch);
}
}
2.遍历二叉树(递归版)
(1)先序递归遍历
Status PreOrder(BiTree BT){ // 先序递归遍历
if(BT){//BT不为空时执行以下语句
visit(BT);
PreOrder(BT->lchild);
PreOrder(BT->rchild);
}
}
(2)中序递归遍历
Status InOrder(BiTree BT){// 中序递归遍历
if(BT){//BT不为空时执行以下语句
InOrder(BT->lchild);
visit(BT);
InOrder(BT->rchild);
}
}
(3)后序递归遍历
Status PostOrder(BiTree BT){// 后序递归遍历
if(BT){//BT不为空时执行以下语句
PostOrder(BT->lchild);
PostOrder(BT->rchild);
visit(BT);
}
}
3.遍历二叉树(非递归版)
(1)先序非递归遍历
//先序非递归遍历二叉树
Status NRPreOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
printf("%c",p->data);
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
}
(2)中序非递归遍历
//中序非递归遍历二叉树
Status NRInOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
printf("%c",p->data);
p=p->rchild;
}
}
}
(3)后序非递归遍历
//后序非递归遍历二叉树
Status NRPostOrder(BiTree BT,Stack &S)
{
BiTNode *p,*r;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
GetTop(S,p); //读栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r){ //若右子树存在,且未被访问过
p=p->rchild; //转向右
}
else{ //否则弹出结点并访问
Pop(S,p);
printf("%c",p->data); //访问该结点
r=p; //记录最近访问的结点
p=NULL; //结点访问完后,重置p指针
}
}
}
}
4.二叉树的层次遍历以及求二叉树宽度和深度
(1)二叉树的层次遍历
Status LevelOrder(BiTree BT,Queue &Q){//按层次非递归遍历二叉树
BiTNode *p;
p=BT;
EnQueue(Q,BT);
while(!EmptyQueue(Q)){ // 队列不为空则进入循环
DeQueue(Q,p); // 出队,即将队头结点出队,因为队列先进先出
visit(p); // 并访问,即加入到最终遍历序列中
if(p->lchild!=NULL) // 如果有左孩子
EnQueue(Q,p->lchild); // 就将左孩子入队
if(p->rchild!=NULL) // 如果有右孩子
EnQueue(Q,p->rchild); // 就将右孩子入队
}
}
(2)求二叉树宽度(使用队列)
//求二叉树的宽度
int TreeWidth(BiTree BT,Queue &Q){
if(BT==NULL) return 0;
int width,max,i,max_i;
BiTree p;
i=1;max_i=i;
width=1;max=width;
EnQueue(Q,BT);
while(!EmptyQueue(Q)){
DeQueue(Q,p);
width--;
if(p -> lchild != NULL) //出队节点的左孩子如果存在则进队
EnQueue(Q, p -> lchild);
if(p -> rchild != NULL)
EnQueue(Q, p -> rchild); //出队节点的右孩子如果存在则进队
if(width==0){//width == 0,表示当前层次i所有节点已遍历完毕,此时队列元素个数即为下一层次 i + 1 的节点个数
width = (Q.rear - Q.front + Maxsize) % Maxsize; //更新宽度
i++;
if(width>max){
max=width;//更新max
max_i=i; //并记录最大宽度所在层次
}
}
}
printf("二叉树第 %d 层的宽度最大\n", max_i);
return max;
}
(3)求二叉树深度(跟高度是一样的)(使用递归)
int TreeDepth(BiTree BT){// 求二叉树的深度
if(BT==NULL) return 0;
else
{
int m = TreeDepth(BT->lchild );
int n = TreeDepth(BT->rchild);
return (m > n) ? (m+1) : (n+1);
}
}
5.求不同类型的结点数目(递归版)
(1)求叶子结点的数目
int LeafNumber(BiTree BT){// 求叶子结点数目
if(BT==NULL){
return 0;
}
else{
int num1=Count1(BT->lchild);
int num2=Count1(BT->rchild);
if((!BT->lchild)&&(!BT->rchild)){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
(2)求单分支结点的数目
int Count1(BiTree BT){//求单分支结点数目
if(BT==NULL){
return 0;
}
else{
int num1=Count1(BT->lchild);
int num2=Count1(BT->rchild);
if((!BT->lchild&&BT->rchild)||(BT->lchild&&!BT->rchild)){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
(3)求双分支结点的数目
int Count2(BiTree BT){//求双分支结点数目 递归算法
if(BT==NULL){
return 0;
}
else{
int num1=Count2(BT->lchild);
int num2=Count2(BT->rchild);
if(BT->lchild&&BT->rchild){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
6.求不同类型的结点数目(非递归版)
就以求双分支结点数目为例
1.利用先序遍历
int Count_two(BiTree BT,Stack &S){//这是求双分支结点数目 非递归算法
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
if(p->lchild&&p->rchild) num++;
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
return num;
}
2.利用中序遍历
int Count_two(BiTree BT,Stack &S){//这是求双分支结点数目 非递归算法
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
if(p->lchild&&p->rchild) num++;
p=p->rchild;
}
}
return num;
}
3.利用后序遍历
//利用后序非递归遍历二叉树 来求双分支结点数目
int Count_two3(BiTree BT,Stack &S)
{
BiTNode *p,*r;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
GetTop(S,p); //读栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r){ //若右子树存在,且未被访问过
p=p->rchild; //转向右
}
else{ //否则弹出结点并访问
Pop(S,p);
if(p->lchild&&p->rchild) num++;
r=p; //记录最近访问的结点
p=NULL; //结点访问完后,重置p指针
}
}
}
return num;
}
因为求单分支结点和叶子结点的方法与之类似(就是将Push函数上面的或者Pop函数下面的if语句里的判断条件改一改就行了),所以这里就不多说了。
三.不常用的操作
1.交换左右子树(递归)
Status ChangeTree(BiTree BT){// 交换左右子树
BiTNode* temp;
temp=BT->lchild;
BT->lchild=BT->rchild;
BT->rchild=temp;
if(BT->lchild){
ChangeTree(BT->lchild);
}
if(BT->rchild){
ChangeTree(BT->rchild);
}
}
2.求二叉树的结点总数
(1)递归版
int Count_All(BiTree BT){//求所有结点数目 递归算法
if(BT==NULL){
return 0;
}
else{
int num1=Count_All(BT->lchild);
int num2=Count_All(BT->rchild);
return num1+num2+1;
}
}
(2)非递归版(利用先序遍历)
int Count_All2(BiTree BT,Stack &S){//这是求所有结点数目 非递归算法 利用先序遍历
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
num++;
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
return num;
}
四.总结
总体代码应该就这么多了,接下来是完整代码(这里因为使用的是输入先序序列构造二叉树的方法,所以这个代码里没有写输入广义表建树的代码):
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"string.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
#define Max_ Tree_SIZE 20
#define StackInitSize 100
#define Maxsize 100
typedef void Status;
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef BiTree SElemType;
typedef struct Stack{
SElemType *top;
SElemType *base;
int size;
}Stack;
bool EmptyStack(Stack S){
if(S.base==S.top)
return true;
return false;
}
Status Pop(Stack &S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
S.top--;
}
Status Push(Stack &S,SElemType e){
if(S.top-S.base>=99)return;
S.top++;
*(S.top)=e;
}
Status GetTop(Stack S,SElemType &e){
if (EmptyStack(S))return;
e=*S.top;
}
Status InitStack(Stack &S){
S.base=S.top=(SElemType *)malloc(StackInitSize*sizeof(SElemType));
if(!S.base)
return;
S.size=StackInitSize;
}
typedef struct{
SElemType data[Maxsize];
int front,rear;
}Queue;
bool EmptyQueue(Queue &a){
if(a.front==a.rear)
return true;
return false;
}
void DeQueue(Queue &a,SElemType &b){//不要疑惑这种写法,这种写法没问题
a.front++;
b=a.data[a.front];
}
void EnQueue(Queue &a,SElemType &b){//EnterQueue
a.rear++;
a.data[a.rear]=b;
}
void InitQueue(Queue &a){
a.front=a.rear=-1;
}
Status InitBiTree(BiTree &BT);
Status CreateBiTree(BiTree *BT);//先序递归创建二叉树
Status PreOrder(BiTree BT);
Status InOrder(BiTree BT);
Status PostOrder(BiTree BT);
int TreeDepth(BiTree BT);
int TreeWidth(BiTree BT,Queue &Q);//求宽度
Status NRPreOrder(BiTree BT,Stack &S);
Status NRInOrder(BiTree BT,Stack &S);
Status NRPostOrder(BiTree BT,Stack &S);
Status LevelOrder(BiTree BT,Queue &Q);
int Count0(BiTree BT);
int Count1(BiTree BT);
int Count2(BiTree BT);
int Count_two(BiTree BT,Stack &S);//求双分支结点数目 非递归算法
int Count_two2(BiTree BT,Stack &S);//这是求双分支结点数目 非递归算法 利用中序遍历
int Count_two3(BiTree BT,Stack &S);//利用后序非递归遍历二叉树 来求双分支结点数目
Status ChangeTree(BiTree BT);
void visit(BiTree a);
void visit(BiTree a){
printf("%c",a->data);
}
Status InitBiTree(BiTree &BT){
BT=(BiTNode*)malloc(sizeof(BiTNode));
BT=NULL;
}
Status CreateBiTree(BiTree *BT){ //status <=> void
char c;
scanf(" %c", &c); // 注意这里的空格,可以读取空格后的字符
if (c == '#'){
*BT = NULL;
}
else{
*BT=(BiTree)malloc(sizeof(BiTNode)); // 这里应该分配的是BiTNode的大小,我假设BiTNode是一个包含左右子树指针和数据字段的结构体
printf("----\n");
(*BT)->data = c;
CreateBiTree(&((*BT)->lchild));
CreateBiTree(&((*BT)->rchild));
}
}
Status PreOrder(BiTree BT){ // 先序递归遍历
if(BT){//BT不为空时执行以下语句
visit(BT);
PreOrder(BT->lchild);
PreOrder(BT->rchild);
}
}
Status InOrder(BiTree BT){// 中序递归遍历
if(BT){//BT不为空时执行以下语句
InOrder(BT->lchild);
visit(BT);
InOrder(BT->rchild);
}
}
Status PostOrder(BiTree BT){// 后序递归遍历
if(BT){//BT不为空时执行以下语句
PostOrder(BT->lchild);
PostOrder(BT->rchild);
visit(BT);
}
}
//int LeafNumber(BiTree BT){// 求叶子结点数目
// if(BT==NULL){
// return 0;
// }
// else{
// if((!BT->lchild)&&(!BT->rchild)) {//左右子树均为空说明是叶子结点
// return 1;
// }
// else{
// return LeafNumber(BT->lchild)+LeafNumber(BT->rchild);
// }
// }
//}
int TreeDepth(BiTree BT){// 求二叉树的深度
if(BT==NULL) return 0;
else
{
int m = TreeDepth(BT->lchild );
int n = TreeDepth(BT->rchild);
return (m > n) ? (m+1) : (n+1);
}
}
//求二叉树的宽度
int TreeWidth(BiTree BT,Queue &Q){
if(BT==NULL) return 0;
int width,max,i,max_i;
BiTree p;
i=1;max_i=i;
width=1;max=width;
EnQueue(Q,BT);
while(!EmptyQueue(Q)){
DeQueue(Q,p);
width--;
if(p -> lchild != NULL) //出队节点的左孩子如果存在则进队
EnQueue(Q, p -> lchild);
if(p -> rchild != NULL)
EnQueue(Q, p -> rchild); //出队节点的右孩子如果存在则进队
if(width==0){//width == 0,表示当前层次i所有节点已遍历完毕,此时队列元素个数即为下一层次 i + 1 的节点个数
width = (Q.rear - Q.front + Maxsize) % Maxsize; //更新宽度
i++;
if(width>max){
max=width;//更新max
max_i=i; //并记录最大宽度所在层次
}
}
}
printf("二叉树第 %d 层的宽度最大\n", max_i);
return max;
}
Status LevelOrder(BiTree BT,Queue &Q){//按层次非递归遍历二叉树
BiTNode *p;
p=BT;
EnQueue(Q,BT);
while(!EmptyQueue(Q)){ // 队列不为空则进入循环
DeQueue(Q,p); // 出队,即将队头结点出队,因为队列先进先出
visit(p); // 并访问,即加入到最终遍历序列中
if(p->lchild!=NULL) // 如果有左孩子
EnQueue(Q,p->lchild); // 就将左孩子入队
if(p->rchild!=NULL) // 如果有右孩子
EnQueue(Q,p->rchild); // 就将右孩子入队
}
}
//!EmptyQueue(Q)
//!EmptyStack(S)
//先序非递归遍历二叉树
Status NRPreOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
printf("%c",p->data);
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
}
//中序非递归遍历二叉树
Status NRInOrder(BiTree BT,Stack &S)
{
BiTNode *p;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
printf("%c",p->data);
p=p->rchild;
}
}
}
//后序非递归遍历二叉树
Status NRPostOrder(BiTree BT,Stack &S)
{
BiTNode *p,*r;
p=BT;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
GetTop(S,p); //读栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r){ //若右子树存在,且未被访问过
p=p->rchild; //转向右
}
else{ //否则弹出结点并访问
Pop(S,p);
printf("%c",p->data); //访问该结点
r=p; //记录最近访问的结点
p=NULL; //结点访问完后,重置p指针
}
}
}
}
int Count0(BiTree BT){// 求叶子结点数目
if(BT==NULL){
return 0;
}
else{
int num1=Count0(BT->lchild);
int num2=Count0(BT->rchild);
if((!BT->lchild)&&(!BT->rchild)){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
int Count1(BiTree BT){//求单分支结点数目
if(BT==NULL){
return 0;
}
else{
int num1=Count1(BT->lchild);
int num2=Count1(BT->rchild);
if((!BT->lchild&&BT->rchild)||(BT->lchild&&!BT->rchild)){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
int Count2(BiTree BT){//求双分支结点数目 递归算法
if(BT==NULL){
return 0;
}
else{
int num1=Count2(BT->lchild);
int num2=Count2(BT->rchild);
if(BT->lchild&&BT->rchild){
return num1+num2+1;
}
else{
return num1+num2;
}
}
}
//求单分支结点和叶子结点数目的非递归算法跟这个差不多
int Count_two(BiTree BT,Stack &S){//这是求双分支结点数目 非递归算法
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
if(p->lchild&&p->rchild) num++;
// printf("%c",p->data);
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
return num;
}
int Count_two2(BiTree BT,Stack &S){//这是求双分支结点数目 非递归算法 利用中序遍历
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
if(p->lchild&&p->rchild) num++;
p=p->rchild;
}
}
return num;
}
//利用后序非递归遍历二叉树 来求双分支结点数目
int Count_two3(BiTree BT,Stack &S)
{
BiTNode *p,*r;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
Push(S,p);
p=p->lchild;
}
else{
GetTop(S,p); //读栈顶节点(非出栈)
if(p->rchild&&p->rchild!=r){ //若右子树存在,且未被访问过
p=p->rchild; //转向右
}
else{ //否则弹出结点并访问
Pop(S,p);
if(p->lchild&&p->rchild) num++;
r=p; //记录最近访问的结点
p=NULL; //结点访问完后,重置p指针
}
}
}
return num;
}
Status ChangeTree(BiTree BT){// 交换左右子树
BiTNode* temp;
temp=BT->lchild;
BT->lchild=BT->rchild;
BT->rchild=temp;
if(BT->lchild){
ChangeTree(BT->lchild);
}
if(BT->rchild){
ChangeTree(BT->rchild);
}
}
int Count_All(BiTree BT){//求所有结点数目 递归算法
if(BT==NULL){
return 0;
}
else{
int num1=Count_All(BT->lchild);
int num2=Count_All(BT->rchild);
return num1+num2+1;
}
}
int Count_All2(BiTree BT,Stack &S){//这是求所有结点数目 非递归算法 利用先序遍历
BiTNode *p;
p=BT;
int num=0;
while(p|| !EmptyStack(S)){
if(p){
num++;
Push(S,p);
p=p->lchild;
}
else{
Pop(S,p);
p=p->rchild;
}
}
return num;
}
int main(){
BiTree BT;
Stack S;
Queue Q;
InitQueue(Q);
InitStack(S);
InitBiTree(BT);
TElemType ch;
int flag=1,select;
printf("To Creat Binary Tree, Please Input PreOrder with '#':");
CreateBiTree(&BT);
//int b=Count_two3(BT,S);
//printf("\n%d",b);
//int a=TreeWidth(BT,Q);
//printf("\n%d",a);
//创建二叉树,返回根结点BT
while (flag){
printf("\nPlease select:\n");
printf("1. PreOrder Traversal\n");
printf("2. InOrder Traversal\n");
printf("3. PostOrder Traversal\n");
printf("4. LevelOrder Traversal\n");
printf("5. NRPreOrder Traversal\n");
printf("6. TreeDepth\n");
printf("7. LeafNumber\n");
printf("8. 求单分支节点数\n");
printf("9. 求双分支节点数\n");
printf("10. 交换左右子树\n");
printf("else. Exit\n");
printf("请输入您的选择:");
scanf("%d",&select);
switch (select){
case 1: printf("The PreOrder Traversal of Binary Tree is: \n ");
PreOrder(BT);
break;
//先序递归遍历
case 2: printf("The InOrder Traversal of Binary Tree is:\n ");
InOrder(BT);
break;
//中序递归遍历
case 3: printf("The PostOrder Traversal of Binary Tree is:\n ");
PostOrder(BT);
break;
//后序递归遍历
case 4: printf("The LevelOrder Traversal of Binary Tree is:\n ");
LevelOrder(BT,Q);
break;
//按层次非递归遍历
case 5: printf("The NRPreOrder Traversal of Binary Tree is:\n ");
NRPreOrder(BT,S);
break;
//先序非递归遍历
case 6: printf("The Depth of Binary Tree is:%d\n ",TreeDepth(BT));
break;
//求高度
case 7: printf("The Number of leaf is:%d \n ",Count0(BT));
break;
//求叶结点数
case 8: printf("单分支节点数目为:%d \n ",Count1(BT));
break;
//求单分支节点
case 9: printf("双分支节点数目为:%d \n ",Count_two(BT,S));
break;
//求双分支节点
case 10:printf("原来树的先序结构为:");
PreOrder(BT);
printf("\n交换后为:");
ChangeTree(BT);
PreOrder(BT);
break;
//交换左右子树
default:printf("您已成功退出,谢谢您的使用!\n");flag=0;
}
}//while
}//main
//ab##c##
//abd##e##cf##g##