您的位置:首页 > 其它

《二叉树的基本操作》

2015-11-28 20:09 357 查看
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define NUM 100            //二叉树的最大结点数
#define QueueSize 100    //队列初始容量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int Status;                //函数结果状态代码
typedef char DataType;            //二叉树结点元素类型为char类型

//二叉树的存储结构
typedef struct node
{
DataType data;                    //结点元素
struct node *lchild,*rchild;    //左右孩子指针
}BinTNode,*BinTree;

typedef BinTNode* ElemType;

//循环队列存储结构
typedef struct
{
ElemType *base;
int front,rear;
}SeQueue;

Status CreateBiTree(BinTree &bt)
{//按照先序遍历次序递归建立二叉树。
//输入ABC##DE#G##F###
char ch;
scanf_s("%c",&ch);
if(ch == '#')    bt = NULL;
else
{
bt = (BinTNode*)malloc(sizeof(BinTNode));
bt->data = ch;    //生成根结点
CreateBiTree(bt->lchild);    //构造左子树
CreateBiTree(bt->rchild);    //构造右子树
}
return OK;
}

Status InorderTraversal(BinTree bt)
{//中序遍历二叉树的非递归方法
BinTNode *stack[NUM];        //定义栈数组
int top = 0;                //初始化栈
stack[top] = bt;
do
{
while(NULL!=stack[top])
{//扫描根结点及其所有的左结点并入栈
top = top + 1;
stack[top] = stack[top-1]->lchild;
}
top = top -1;        //退栈
if(top>=0)            //判断栈是否为空
{
printf("%3c",stack[top]->data);    //访问结点
stack[top] = stack[top]->rchild;    //扫描右子树
}
}while(top>=0);
return OK;
}

void PreOrderTraversal(BinTree bt)
{//先序遍历二叉树
if(bt)
{
printf("%3c",bt->data);
PreOrderTraversal(bt->lchild);
PreOrderTraversal(bt->rchild);
}
}

void InOrderTraversal(BinTree bt)
{//中序遍历二叉树
if(bt)
{
InOrderTraversal(bt->lchild);
printf("%3c",bt->data);
InOrderTraversal(bt->rchild);
}
}
void PostOrder(BinTree bt)
{//后序遍历二叉树
if(bt)
{
PostOrder(bt->lchild);
PostOrder(bt->rchild);
printf("%3c",bt->data);
}
}

int Size(BinTree bt)
{//统计二叉树中所有结点的个数
int num1,num2;
if(bt==NULL)
return 0;
else if(bt->lchild==NULL && bt->rchild==NULL)
return 1;
else
{
num1 = Size(bt->lchild);    //统计左子树的结点个数
num2 = Size(bt->rchild);    //统计右子树的结点个数
return (num1+num2+1);
}
}

int LeafCount(BinTree bt)
{//统计二叉树的叶子总数
int LeafNum;
if(bt==NULL)
LeafNum = 0;
else if((bt->lchild==NULL) && (bt->rchild==NULL))
LeafNum = 1;
else
LeafNum = LeafCount(bt->lchild)+LeafCount(bt->rchild);    //叶子总数为左右子树叶子之和
return LeafNum;
}

int Depth(BinTree bt)
{//统计二叉树的深度
int hl,hr,max;
if(bt!=NULL)
{
hl = Depth(bt->lchild);    //求左子树的深度
hr = Depth(bt->rchild);    //求右子树的深度
max = hl>hr?hl:hr;
return (max+1);            //返回树的深度
}
else
return 0;
}

void Exchange(BinTree bt)
{//交换左右二叉树
if(bt == NULL)
return;
BinTNode *temp;
temp = bt->lchild;
bt->lchild = bt->rchild;
bt->rchild = temp;
Exchange(bt->lchild);
Exchange(bt->rchild);
}

//构造一个循环队列
Status InitQueue(SeQueue &Q)
{
Q.base = (ElemType*)malloc(QueueSize*sizeof(ElemType));
if(!Q.base)        exit(0);
Q.front = Q.rear = 0;
return OK;
}

//插入新的元素为队尾元素
Status EnQueue(SeQueue &Q,ElemType e)
{//插入的元素为二叉树结点中的元素
if((Q.rear+1)%QueueSize == Q.front)
{
printf("Queue overflow");
return 0;
}
Q.base[Q.rear] = e;
Q.rear = (Q.rear+1)%QueueSize;
return 1;
}

//删除队头元素
Status DeleteQ(SeQueue &Q,ElemType &e)
{
if(Q.front == Q.rear)
{
printf("Queue empty");
return ERROR;
}
e = Q.base[Q.front];
Q.front = (Q.front+1)%QueueSize;
return OK;
}

//判空循环队列
Status IsEmptyQ(SeQueue Q)
{
if(Q.front == Q.rear)
return TRUE;
else
return FALSE;
}

//层次遍历二叉树
void LevelOrderTraversal(BinTree bt)
{
SeQueue Q;
ElemType e;
InitQueue(Q);        //创建并初始化队列
if(bt)    EnQueue(Q,bt);
while(!IsEmptyQ(Q))
{
DeleteQ(Q,e);
printf("%3c",e->data);
if(e->lchild)    EnQueue(Q,e->lchild);
if(e->rchild)    EnQueue(Q,e->rchild);
}
}

void main()
{
BinTree bt;
int xz = 1;
int yz,sd;
while(xz)
{
printf("\t*************************************\n");
printf("\t\t二叉树的建立及其基本操作\n");
printf("\t*************************************\n");
printf("\t==============================\n");
printf("\t1,建立二叉树的存储结构\n");
printf("\t2,二叉树的基本操作\n");
printf("\t3,交换二叉树的左右子树\n");
printf("\t4,二叉树的层次遍历\n");
printf("\t0,退出系统\n");
printf("\t==============================\n");
printf("\t请选择:(0~4)\n");
scanf("%d",&xz);
getchar();
switch(xz)
{//输入:ABC##DE#G##F###
case 1:
printf("输入二叉树的先序序列结点值:\n");
CreateBiTree(bt);
printf("二叉树的链式存储结构建立完成\n");
printf("\n");
break;
case 2:
printf("该二叉树的先序遍历序列是:");
PreOrderTraversal(bt);    //输出ABCDEGF
printf("\n");
printf("该二叉树的中序遍历序列是:");
InOrderTraversal(bt);    //输出CBEGDFA
printf("\n");
printf("该二叉树的后序遍历序列是:");
PostOrder(bt);            //输出CGEFDBA
printf("\n");
printf("该二叉树的中序遍历序列是(非递归算法):");
InorderTraversal(bt);    //输出CBEGDFA
printf("\n");
printf("该二叉树的结点个数是:%d\n",Size(bt));
yz = LeafCount(bt);
printf("叶子结点个数是:%d",yz);
printf("\n");
sd = Depth(bt);
printf("该二叉树的深度是:%d\n",sd);
printf("\n");
break;
case 3:
Exchange(bt);
printf("该二叉树意已交换左右子树\n");
printf("\n");
printf("交换左右子树后,先序遍历序列是:");
PreOrderTraversal(bt);
printf("\n");
printf("交换左右子树后,中序遍历序列是:");
InorderTraversal(bt);
printf("\n");
printf("交换左右子树后,后序遍历序列是:");
PostOrder(bt);
printf("\n");
break;
case 4:
printf("该二叉树的层次遍历序列是:");
LevelOrderTraversal(bt);
printf("\n");    //输出ABCDEFG
case 0:
break;
default:printf("输入的选项没有对应的操作,请重新选择:\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: