数据结构二叉树操作

 
 
#include <stdio.h>
#include <malloc.h>
#include <conio.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#define Stack_Size 50 /*栈的最大长度*/
#define MAXSIZE 50 /*队列的最大长度*/

typedef char DataType;

typedef struct Node
{
DataType data;
struct Node *LChild;
struct Node *RChild;
}BiTNode, *BiTree;

/*----------------定义栈-----------------*/
typedef BiTree StackElementType;
typedef struct
{
StackElementType elem[Stack_Size]; /*用来存放栈中元素的一维数组*/
int top; /*用来存放栈顶元素的下标,top为-1表示空栈*/
}SeqStack;

/*----------------定义队-------------*/
typedef BiTree QueueElementType;
typedef struct
{
QueueElementType element[MAXSIZE]; /* 队列的元素空间*/
int front; /*头指针指示器*/
int rear; /*尾指针指示器*/
}SeqQueue;

/*-------------处理栈---------------*/
/*初始化*/
void InitStack(SeqStack *S)
{
/*构造一个空栈S*/
S->top = -1;
}

/*判栈空*/
int IsEmpty(SeqStack *S) /*判断栈S为空栈时返回值为真,反之为假*/
{
return(S->top==-1?TRUE:FALSE);
}

/*判栈满*/
int IsFull(SeqStack *S) /*判断栈S为满栈时返回值为真,反之为假*/
{
return(S->top==Stack_Size-1?TRUE:FALSE);
}

/*入栈*/
int Push(SeqStack *S,StackElementType x)
{
if(S->top==Stack_Size-1)
return(FALSE); /*栈已满*/
S->top++;
S->elem[S->top] = x;
return(TRUE);
}

/*出栈*/
int Pop(SeqStack *S,StackElementType *x)
{
/* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
if(S->top == -1) /*栈为空*/
return(FALSE);
else
{
*x = S->elem[S->top];
S->top--; /* 修改栈顶指针 */
return(TRUE);
}
}
/*------------------处理队--------------------*/
/*初始化操作*/
void InitQueue(SeqQueue *Q)
{
/* 将*Q初始化为一个空的循环队列 */
Q->front=Q->rear=0;
}

/*入队操作*/
int EnterQueue(SeqQueue *Q, QueueElementType x)
{
/*将元素x入队*/
if((Q->rear+1)%MAXSIZE==Q->front) /*队列已经满了*/
return(FALSE);
Q->element[Q->rear]=x;
Q->rear=(Q->rear+1)%MAXSIZE; /* 重新设置队尾指针 */
return(TRUE); /*操作成功*/
}

/*出队操作*/
int DeleteQueue(SeqQueue *Q, QueueElementType *x)
{
/*删除队列的队头元素,用x返回其值*/
if(Q->front==Q->rear) /*队列为空*/
return(FALSE);
*x=Q->element[Q->front];
Q->front=(Q->front+1)%MAXSIZE; /*重新设置队头指针*/
return(TRUE); /*操作成功*/
}

int IsEmptyQueue(SeqQueue *Q) /*提取队列的队头元素,用x返回其值*/
{
if(Q->front==Q->rear) /*队列为空*/
return(TRUE);
else
return(FALSE); /*操作成功*/
}

/*------------------创建树------------------*/
void CreateBiTree(BiTree *bt)
{
char ch;
ch = getchar();
if(ch=='.') *bt=NULL;
else
{
*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点
(*bt)->data=ch;
CreateBiTree(&((*bt)->LChild)); //生成左子树
CreateBiTree(&((*bt)->RChild)); //生成右子树
}
}

/*------------------遍历处理----------------------*/
void Visit(char ch)
{
printf("%c ",ch);
}

void PreOrder(BiTree root)
/*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/
{
if (root!=NULL)
{
Visit(root ->data); /*访问根结点*/
PreOrder(root ->LChild); /*先序遍历左子树*/
PreOrder(root ->RChild); /*先序遍历右子树*/
}
}

void InOrder(BiTree root)
/*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/
{
if (root!=NULL)
{
InOrder(root ->LChild); /*中序遍历左子树*/
Visit(root ->data); /*访问根结点*/
InOrder(root ->RChild); /*中序遍历右子树*/
}
}

void PostOrder(BiTree root)
/* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/
{
if(root!=NULL)
{
PostOrder(root ->LChild); /*后序遍历左子树*/
PostOrder(root ->RChild); /*后序遍历右子树*/
Visit(root ->data); /*访问根结点*/
}
}

void FFInOrder(BiTree root) /* 中序遍历二叉树的非递归算法 */
{
SeqStack S;
BiTree p;
InitStack (&S);
p=root;
while(p!=NULL || !IsEmpty(&S))
{
if (p!=NULL) /* 根指针进栈,遍历左子树 */
{
Push(&S,p);
p=p->LChild;
}
else
{ /*根指针退栈,访问根结点,遍历右子树*/
Pop(&S,&p);
Visit(p->data);
p=p->RChild;
}
}
}

int LayerOrder(BiTree bt) //层次遍历
{
SeqQueue *Q;
BiTree p;
Q=(SeqQueue *)malloc(sizeof(SeqQueue));
//p=(BiTree *)malloc(sizeof(BiTree));
InitQueue(Q); /*初始化空队列Q*/
if(bt == NULL)
return ERROR; /* 若二叉树bt为空树,则结束遍历*/
EnterQueue(Q, bt);/* 若二叉树bt非空,则根结点bt入队,开始层次遍历*/
while(!IsEmptyQueue(Q)) /*若队列非空,则遍历为结束,继续进行*/
{
DeleteQueue(Q, &p);/*队头元素出队并访问 */
printf("%c ",p->data);
if(p->LChild )
EnterQueue(Q, p->LChild);/*若p的左孩子非空,则进队*/
if(p->RChild )
EnterQueue(Q, p->RChild); /*若p的右孩子非空,则进队*/
}/*while*/
return OK;
}/* LayerOrder */

/*----------------二叉树的高度----------------*/
int PostTreeDepth(BiTree bt) /* 后序遍历求二叉树的高度递归算法 */
{
int hl,hr,max;
if(bt!=NULL)
{
hl=PostTreeDepth(bt->LChild); /* 求左子树的深度 */
hr=PostTreeDepth(bt->RChild); /* 求右子树的深度 */
max=hl>hr?hl:hr; /* 得到左、右子树深度较大者*/
return(max+1); /* 返回树的深度 */
}
else return(0); /* 如果是空树,则返回0 */
}

/*----------------叶子节点个数----------------*/

int leafTree(BiTree root)
{
int LeafCount;
if(root==NULL)
LeafCount =0;
else
if((root->LChild==NULL)&&(root->RChild==NULL))
LeafCount =1;
else
LeafCount =leafTree(root->LChild)+leafTree(root->RChild);
/* 叶子数为左右子树的叶子数目之和 */
return LeafCount;
}

void PrintTree(BiTree Boot,int nLayer)
{
int i=0;
if(Boot == NULL) return;
PrintTree(Boot->RChild,nLayer+1);
for(i=0;i<nLayer;i++)
printf(" ");
printf("%c\n",Boot->data);
PrintTree(Boot->LChild,nLayer+1);
}

/*----------------交换左右孩子----------------*/

/*void swapChild(BiTree bt)
{
if(bt==NULL)
return;
BiTree temp=(BiTree)malloc(sizeof(BiTree));
swapChild(bt->LChild);
swapChild(bt->RChild);
temp=bt->LChild;
bt->LChild=bt->RChild;
bt->RChild=temp;
}
*/
void Change(BiTree bt) {
if (bt != NULL) {
BiTree temp = (BiTree)malloc(sizeof(BiTree));
if (temp != NULL)
{
temp = bt->RChild;
bt->RChild = bt->LChild;
bt->LChild = temp;
}
else
Change(bt);
Change(bt->LChild);
Change(bt->RChild);
}
}

void main()
{
BiTree T;
char number1,number2;
int Layer=0;
int h;
int LeafCount;
printf("*******************二叉树的操作!*********************\n");
printf("按扩展先序遍历序列建立二叉树,请输入序列:\n");
CreateBiTree(&T);
printf("\n二叉树的形状如下:\n");
PrintTree(T,Layer);
//------------二叉树的具体操作------------
do{
printf("\n");
printf("***********************************************\n");
printf("请选择二叉树的具体操作,输入9表示推出!\n");
printf("A.二叉链表的建立!\n");
printf("B.二叉树的遍历:\n");
printf("C.二叉树的高度\n");
printf("D.二叉树的节点个数!\n");
printf("E.交换二叉树的左右孩子!\n");
printf("F.清空二叉树!\n");
printf("***********************************************");
printf("\n");
number1 = getch();
switch(number1){
case 'A':
printf("\n二叉链表的建立!\n");
PrintTree(T,Layer);
printf("\n建立成功!\n");
break;
case 'B':
//遍历
do{
printf("\n");
printf("***********************************************\n");
printf("请选择菜单遍历二叉树,输入0表示退出:\n");
printf("1.先序遍历\n");
printf("2.中序遍历\n");
printf("3.后序遍历\n");
printf("4.分层遍历\n");
printf("5.中序遍历非递归算法\n");
printf("***********************************************");
printf("\n");
number2=getch();
switch(number2){
case '0':
break;
case '1':
printf("\n--->先序遍历的结果:");
PreOrder(T); //先序遍历
printf("\n");
break;
case '2':
printf("\n--->中序遍历的结果:");
InOrder(T); // 中序遍历
printf("\n");
break;
case '3':
printf("\n--->后序遍历的结果:");
PostOrder(T);; //后序遍历
printf("\n");
break;
case '4':
printf("\n--->分层遍历的结果:");
LayerOrder(T);;//分层遍历
printf("\n");
break;
case '5':
printf("5.中序遍历非递归算法:");
FFInOrder(T);
break;
default:
;
}
}while(number2!='0');
break;

case 'C':
h = PostTreeDepth(T);
printf("\n--->二叉树的高度high=:%d",h);
// printf("%d",(max+1));
printf("\n");
break;

case 'D':
leafTree(T);
printf("\n--->二叉树的节点个数为countTree=:%d",LeafCount);
//printf("%d",LeafCount);
printf("\n");
break;

case 'E':
printf("\n--->交换二叉树的左右孩子!\n");
//swapChild(&T);
Change(T);
PrintTree(T,Layer);
printf("\n交换成功!");
break;

case 'F':
printf("\n--->退出二叉树的操作!\n");
printf("\n退出成功!");
break;

default:
break;
}//第一个switch
}while(number1!=9);//end 第一个do
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值