【二叉排序树与文件操作】
功能要求:
(1)从键盘输入一组学生记录建立二叉排序树;
(2)二叉排序树存盘;
(3)由文件恢复内存的二叉排序树;
(4)中序遍历二叉排序树;
(5)求二叉排序树深度;
(6)求二叉排序树的所有节点数和叶子节点数;
(7)向二叉排序树插入一条学生记录;
(8)从二叉排序树中删除一条学生记录;
(9)从二叉排序树中查询一条学生记录;
(10)以广义表的形式输出二叉排序树
等功能。
//定义学生记录类型
Struct student {
Char num[6];//学号
Int grade;//成绩
};
//定义二叉排序树节点值的类型为学生记录类型
typedef student ElemType;
//定义二叉排序树的节点类型
typedef Struct BSTNode {
ElemType data;
Struct BSTNode *left;
Struct BSTNode *rchild;
} BSTNode;
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
struct student {
char num[6];//学号
int grade;//成绩
};
typedef student ElemType;
typedef struct BSTNode {
ElemType data;
struct BSTNode *lchild;
struct BSTNode *rchild;
} BSTNode,*BSTree;
BSTNode *pre=NULL;
int n;
int found(BSTree T,char c[]) ///查找
{
BSTNode *p=T;
while (p !=NULL)
{
if (strcmp(p->data.num,c)==0)
{
return 1;
}
else
if (strcmp(p->data.num,c)>0)
{
pre=p;p=p->lchild; ///查左子树;
}
else
{
pre=p;p=p->rchild; ///查右子树;
}
}
return 0;
}
void insert(BSTree &T,student a)///插入算法
{
BSTree s;
char c[6];
strcpy(c,a.num);
if (found(T,c)==0)
{
s=(BSTree)malloc(sizeof(BSTNode));
s->data=a;
s->lchild=NULL;
s->rchild=NULL;
if (T==NULL)
{T=s;} ///新结点作为根结点;
else if(strcmp(s->data.num,pre->data.num)<0)
pre->lchild=s; ///插入左子树;
else pre->rchild=s; ///插入右子树;
}
}
void InOrderTraverse(BSTree T)
{///中序遍历算法
if (T!=NULL)
{
InOrderTraverse(T->lchild);
cout<<T->data.num<<" "<<T->data.grade<<endl;
InOrderTraverse(T->rchild);
}
}
int Delete(BSTree &p)/// 从二叉排序树中删除节点p, 并重接它的左或右子树
{
BSTree q, s;
if( !p->lchild && !p->rchild ) /* p为叶子节点 */
p = NULL;
else if( !p->lchild ) /* 左子树为空,接右子树 */
{
q = p;
p = p->rchild;
free(q);
}
else if( !p->rchild ) /* 右子树为空,接左子树 */
{
q = p;
p = p->lchild;
free(q);
}
else /* 左右子树均不为空 */
{
q = p;
s = p->lchild;
while(s->rchild) /* 转左,然后向右走到尽头*/
{
q = s;
s = s->rchild;
}
strcpy(p->data.num,s->data.num);
if( q != p ) /* 判断是否执行上述while循环 */
q->rchild = s->lchild; /* 执行上述while循环,重接右子树 */
else
q->lchild = s->lchild; /* 未执行上述while循环,重接左子树 */
free(s);
}
cout<<"删除成功\n";
n--;
return 1;
}
int DeleteBST(BSTree &T, student a)
{
char c[6];
strcpy(c,a.num);
if(found(T,c)==0)
printf("无节点\n");
else
{
if( strcmp(c,T->data.num)==0)
Delete(T);
else if( strcmp(c,T->data.num)<0)
return DeleteBST(T->lchild, a);
else
return DeleteBST(T->rchild, a);
}
}
void F1( BSTree &t)
{
t=NULL;
int i;
student a;
printf("输入节点数量:\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("请输入第%d节点:\n",i);
cout<<"学号:";
cin>>a.num;
cout<<"成绩:";
cin>>a.grade;
insert(t,a);
}
}
void F22(BSTree T,FILE *w){///先序遍历二叉树的递归算法
if (T){
fprintf(w,"%s %d\n",T->data.num,T->data.grade);
F22(T->lchild,w);
F22(T->rchild,w);
}
}
void F2(BSTree T)
{///先序遍历(存盘)算法
FILE *w=fopen("D:\\text.txt","w+");
F22(T,w);
cout<<"存盘成功\n";
fclose(w);
}
BSTree F3()///从文件中读取先序序列重建二叉排序树
{ FILE *w=fopen("D:\\text.txt","r+");
student a;
n=0;
BSTree t=NULL;
while(!feof(w))
{
fscanf(w,"%s %d\n",&a.num,&a.grade);
insert(t,a);n++;
}
fclose(w);
return t;
}
int F5(BSTree T){///求二叉树深度
int depl,depr;
if (T==NULL) return 0;
else {
depl=F5(T->lchild);
depr=F5(T->rchild);
if (depl>=depr) return (depl+1);
else return (depr+1);
}
}
int F6(BSTree T) ///求叶子结点的个数
{if(!T) return 0; //空树没有叶子
else
if(T->lchild==NULL&&T->rchild==NULL) return 1; //叶子结点
else return F6(T->lchild)+F6(T->rchild);
//左子树叶子数加上右子树叶子数
}
void F7(BSTree t)
{
student a;
cout<<"请输入新增的学生信息:\n";
cout<<"学号:";cin>>a.num;
cout<<"\n成绩:";cin>>a.grade;
insert(t,a);
n++;
cout<<"插入成功\n";
}
void F8(BSTree t)
{
student a;
printf("\n请输入要删除的节点:\n");
scanf("%s",a.num);
DeleteBST(t,a);
}
void F9(BSTree t)
{
BSTNode *p=t;
char c[7];
cout<<"请输入要查询的学号:";
cin>>c;
int flag=0;
while (p !=NULL)
{
if (strcmp(p->data.num,c)==0)
{
cout<<"查询到记录如下:\n";
cout<<"学号: "<<p->data.num<<" 成绩:"<<p->data.grade<<endl;
flag=1;break;
}
else
if (strcmp(p->data.num,c)>0)
{
pre=p;p=p->lchild; ///查左子树;
}
else
{
pre=p;p=p->rchild; ///查右子树;
}
}
if(flag==0)
cout<<"未查询到相关数据\n";
return ;
}
void F10(BSTree t)
{
if(t!=NULL)
{
cout<<t->data.num;//<<" "<<t->data.grade;
if(t->lchild!=NULL||t->rchild!=NULL)
{
cout<<"(";
F10(t->lchild);
if(t->rchild!=NULL)
{
cout<<",";
}
F10(t->rchild);
cout<<")";
}
}
}
void init()
{ cout<<"请选择操作\n";
cout<<"(1)从键盘输入一组学生记录建立二叉排序树;\n";
cout<<"(2)二叉排序树存盘;\n";
cout<<"(3)由文件恢复内存的二叉排序树;\n";
cout<<"(4)中序遍历二叉排序树;\n";
cout<<"(5)求二叉排序树深度;\n";
cout<<"(6)求二叉排序树的所有节点数和叶子节点数;\n";
cout<<"(7)向二叉排序树插入一条学生记录;\n";
cout<<"(8)从二叉排序树中删除一条学生记录;\n";
cout<<"(9)从二叉排序树中查询一条学生记录;\n";
cout<<"(10)以广义表的形式输出二叉排序树\n";
}
void solve()
{ BSTree t=NULL;
int a,aa;
init();
while(cin>>a)
{ int f=0;
switch(a)
{
case 0:f==1;break;
case 1:F1(t);break;
case 2:F2(t);break;
case 3:t=F3();break;
case 4:InOrderTraverse(t);break;
case 5: aa=F5(t);cout<<"二叉排序树深度为: "<<aa;break;
case 6: aa=F6(t);cout<<"二叉排序树的所有节点数为:"<<n<<" 二叉排序树的叶子节点数为:"<<aa;break;
case 7:F7(t);break;
case 8:F8(t);break;
case 9:F9(t);break;
case 10:F10(t);break;
}
if(f==1)break;
cout<<endl;
init();
}
return ;
}
int main()
{
solve();
return 0;
}
测试数据
10
201533
45
201522
56
201544
65
201511
96
201523
96
201537
89
201566
79
201524
93
201555
64
201578
91