#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "btree.h"
#define COUNT 20
void CreateBTree(BTNode *&b,char *str) //接收一个符号表示法的二叉树字符串,创建为一个二叉树结构
{
BTNode *St[MAXSIZE],*p;
int top = -1,k,j=0;
char ch;
b = NULL;
ch = str[j];
while(ch!='\0')
{
switch(ch)
{
case'(':
{
top++; St[top]=p; k=1;break;
}
case')':
{
top--;break;
}
case',':
{
k=2;break;
}
default:
{
p = (BTNode*)malloc(sizeof(BTNode));
p->name = ch;
p->data = j;
p->Lchild = p->Rchild =NULL;
}
if(b==NULL)
{
b=p;
}
else
{
switch(k)
{
case 1:St[top]->Lchild = p; break;
case 2:St[top]->Rchild = p; break;
}
}
}
j++;
ch = str[j];
}
}
void DestoryBTree(BTNode *b) //销毁二叉树
{
if(b!=NULL)
{
DestoryBTree(b->Lchild);
DestoryBTree(b->Rchild);
free(b);
}
}
BTNode* FindNode(BTNode *b,int x) //定位存储某一数据的结点,并返回该结点
{
BTNode *p;
if(b == NULL)
{
return NULL;
}
if(b->data==x)
{
return b;
}
else
{
p = FindNode(b->Lchild,x);
if(p!=NULL)
{
return p;
}
else
{
return FindNode(b->Rchild,x);
}
}
}
BTNode *LChildNode(BTNode *b) //找寻某一结点的左孩子结点
{
return b->Lchild;
}
BTNode *RChildNode(BTNode *b) //找寻某一结点的右孩子结点
{
return b->Rchild;
}
int BTHeight(BTNode *b) //求树的高度
{
int Lch_H,Rch_H;
if(b==NULL)
{
return (0);
}
else
{
Lch_H = BTHeight(b->Lchild);
Rch_H = BTHeight(b->Rchild);
return (Lch_H > Rch_H)?(Lch_H+1):(Rch_H+1);
}
}
void DispBTree(BTNode *b) //在终端中输出二叉树(括号表示法)
{
if(b!=NULL)
{
printf("%c",b->name);
if(b->Lchild != NULL || b->Rchild != NULL)
{
printf("(");
DispBTree(b->Lchild);
if(b->Rchild != NULL)
{
printf(",");
}
DispBTree(b->Rchild);
printf(")");
}
}
}
void DispBTree_Data(BTNode *b) //在终端中输出二叉树中所有结点存储的数据值
{
if(b!=NULL)
{
printf("%d",b->data);
if(b->Lchild != NULL || b->Rchild != NULL)
{
printf("(");
DispBTree_Data(b->Lchild);
if(b->Rchild != NULL)
{
printf(",");
}
DispBTree_Data(b->Rchild);
printf(")");
}
}
}
void WriteData(char *FileName, int size, int type) //生成伪随机数
{
int i,j;
FILE *fp;
srand((unsigned)time(NULL));
if ((fp=fopen(FileName, "w"))==NULL)
{
printf("No such file exist.");
exit (0);
}
if (type==1)
{
printf("\n------------------random integers----------------\n");
}
for (i=0;i<size;i++)
{
j=rand()%99;
fprintf(fp,"%d\n", j);
if (type==1)
{
printf("%d ",j);
}
}
fclose(fp);
printf("\n");
}
void GetData(char *FileName,int array[]) //将写入文件中的数据存储到数组中
{
FILE *fp;
int data,i=0;
if ((fp=fopen(FileName, "r"))==NULL)
{
printf("No such file exist.");
exit (0);
}
else
{
while (fscanf(fp,"%ld",&data)!=EOF)
{
array[i] = data;
i++;
}
}
fclose(fp);
}
BTNode* BTName(BTNode *b,char name) //根据某一结点名字返回该结点
{
BTNode *p;
if(b==NULL||(b->Lchild==NULL&&b->Lchild==NULL))
{
return NULL;
}
if(b->name == name)
{
return b;
}
p = BTName(b->Lchild,name);
if(p!=NULL)
{
return p;
}
else
{
return BTName(b->Rchild,name);
}
}
BTNode* SeqTree(BTNode *&b,int a) //二叉排序树的实现
{
if(b == NULL)
{
b = (BTNode*)malloc(sizeof(BTNode));
b->data = a;
b->Lchild = b->Rchild = NULL;
}
else
{
if(b->data <= a)
{
return SeqTree(b->Rchild,a);
}
else
{
return SeqTree(b->Lchild,a);
}
}
}
void PreOrder(FILE *fp,BTNode *b) //先序遍历
{
if(b != NULL)
{
fprintf(fp,"%d ",b->data);
PreOrder(fp,b->Lchild);
PreOrder(fp,b->Rchild);
}
}
void InOrder(FILE *fp,BTNode *b) //中序遍历
{
if(b != NULL)
{
InOrder(fp,b->Lchild);
fprintf(fp,"%d ",b->data);
InOrder(fp,b->Rchild);
}
}
void PostOrder(FILE *fp,BTNode *b) //后序遍历
{
if(b != NULL)
{
PostOrder(fp,b->Lchild);
PostOrder(fp,b->Rchild);
fprintf(fp,"%d ",b->data);
}
}
int main()
{
printf("============二叉树ADT============\n\n"); //二叉树基本操作
int x;
char str[0];
BTNode *b;
printf("请输入一个要创建的树(括号表示法):");
scanf("%s",str);
CreateBTree(b,str);
printf("被创建的树为:");
DispBTree(b);
printf("\n");
getchar();
printf("该树的高度为%d\n\n",BTHeight(b));
printf("请输入一个要搜索的结点数据:");
scanf("%d",&x);
if(FindNode(b,x)==NULL)
{
printf("没有在该树内找到这一结点\n");
}
else
{
printf("存储%d的结点为:%c\n",x,FindNode(b,x)->name);
}
char name;
BTNode *t;
printf("请输入要找寻孩子结点的结点:");
getchar();
scanf("%c",&name);
t = BTName(b,name);
if(t==NULL)
{
printf("该结点没有孩子结点\n");
}
else
{
printf("%c的左孩子结点为%c,右孩子结点为%c\n",name,LChildNode(t)->name,RChildNode(t)->name);
}
DestoryBTree(b);
printf("销毁此树");
printf("============二叉排序树============\n\n"); //二叉排序树和二叉树遍历
int array[COUNT];
char change;
BTNode *p = NULL;
WriteData("RandomData.txt",COUNT,1);
printf("是否要手动改变生成随机数?(是/Y)(否/N)");
getchar();
scanf("%c",&change);
switch(change)
{
case'Y':
{
FILE *fp;
if((fp=fopen("RandomData.txt","w"))==NULL)
{
printf("No such file exist.");
exit (0);
}
else
{
int change_number;
for(int i=0; i<COUNT; i++)
{
printf("请手动输入第%d个数字:",i+1);
scanf("%d",&change_number);
fprintf(fp,"%d\n",change_number);
}
}
fclose(fp);
break;
}
case'N':
{
printf("pass...\n\n");break;
}
}
GetData("RandomData.txt",array);
for(int i=0; i<COUNT; i++)
{
SeqTree(p,array[i]);
}
printf("根据随机数生成的二叉排序树为:");
DispBTree_Data(p);
FILE *fp;
if((fp=fopen("DataOrder.txt","w"))==NULL)
{
printf("No such file exist.");
exit (0);
}
else
{
fprintf(fp,"先序遍历:");
PreOrder(fp,p);
fprintf(fp,"\n");
fprintf(fp,"中序遍历:");
InOrder(fp,p);
fprintf(fp,"\n");
fprintf(fp,"后序遍历:");
PostOrder(fp,p);
fprintf(fp,"\n");
fclose(fp);
}
}
btree.h头文件
运行结果
生成的随机数
二叉树遍历