1、二叉排序树与文件操作
功能要求:
(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 <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <fstream>
#include <windows.h>
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,*BiTree;
BiTree Search(BiTree T,int key)
{
if (!T)
{
return NULL;
}
if (key > T->data.grade)
{
return Search(T->rchild,key);
}
else if (key < T->data.grade)
{
return Search(T->lchild,key);
}
else
{
return T;
}
}
void Insert(BiTree &T,char *num,int key)
{
BiTree p;
p=new BSTNode;
p->data.grade=key;
strcpy(p->data.num,num);
p->lchild=p->rchild=NULL;
if (!T)
{
T=p;
return;
}
if (Search(T,key)!=NULL)
{
return;
}
BiTree tnode=NULL;
BiTree troot=T;
while(troot)
{
tnode=troot;
if (key < troot->data.grade)
{
troot = troot->lchild;
}
else
{
troot = troot->rchild;
}
}
if (key < tnode->data.grade)
tnode->lchild = p;
else
tnode->rchild = p;
}
int Search_Line(BiTree T,char *s)
{
queue<BiTree>q;
q.push(T);
while(!q.empty())
{
BiTree t=q.front();
q.pop();
if (strcmp((t->data.num),s)==0)
{
return t->data.grade;
}
if (t->lchild)
{
q.push(t->lchild);
}
if (t->rchild)
{
q.push(t->rchild);
}
}
}
void MidOrderTraverse(BiTree T)
{
if (T)
{
MidOrderTraverse(T->lchild);
cout<<T->data.num<<" "<<T->data.grade<<endl;
MidOrderTraverse(T->rchild);
}
}
void Delete(BiTree T,int key)
{
BiTree p=T,q=NULL,s=NULL,f=NULL;
if (!p)
{
return ;
}
while(p)
{
if (p->data.grade==key)
{
break;
}
f=p;
if (p->data.grade>key)
{
p=p->lchild;
}
else
{
p=p->rchild;
}
}
q=p;
if (p->lchild&&p->rchild)
{
s=p->lchild;
while(s->rchild)
{
q=s;
s=s->rchild;
}
p->data=s->data;
if (q!=p)
{
q->rchild=s->lchild;
}
else
{
q->lchild=s->lchild;
}
delete s;
return ;
}
else if (!p->rchild)
{
p=p->lchild;
}
else if (!p->lchild)
{
p=p->rchild;
}
if (!f)
{
T=p;
}
else if (q==f->lchild)
{
f->lchild=p;
}
else
{
f->rchild=p;
}
delete q;
}
int count(BiTree T)
{
if(T == NULL)
{
return 0;
}
else if ((T->lchild==NULL) && (T->rchild==NULL))
{
return 1;
}
else
{
return count(T->lchild)+count(T->rchild);
}
}
int numbers(BiTree T)
{
int sum=0;
if (!T)
{
sum++;
}
else
{
sum=1+numbers(T->lchild)+numbers(T->rchild);
}
return sum;
}
int Depth(BiTree T)
{
if (T==NULL)
{
return 0;
}
else
{
int m=Depth(T->lchild);
int n=Depth(T->rchild);
if (m>n)
{
return m+1;
}
return n+1;
}
}
void f_write(BiTree T)
{
ofstream open("11.txt");
if (!open.is_open())
{
cout<<"文件打开失败!"<<endl;
return;
}
queue<BiTree>q;
q.push(T);
while(!q.empty())
{
BiTree t=q.front();
q.pop();
open<<t->data.num<<" "<<t->data.grade<<endl;
if (t->lchild)
{
q.push(t->lchild);
}
if (t->rchild)
{
q.push(t->rchild);
}
}
cout<<"文件打开成功!"<<endl;
open.close();
}
void f_read(BiTree &T)
{
// T->lchild=NULL;
//T->rchild=NULL;
FILE *fp;
fp = fopen("11.txt", "r");
if (fp == NULL)
{
printf("Open File failed.\n");
return;
}
int a;
char str[6];
while (!feof(fp))
{
fscanf(fp, "%s %d", &str, &a);
//printf("Line:%s %d\n", str, a);
Insert(T,str,a);
}
cout<<"文件打开成功!"<<endl;
fclose(fp);
}
void Put(BiTree T)
{
if(T!=NULL)
{
cout<<T->data.num;
if(T->lchild!=NULL||T->rchild!=NULL)
{
cout<<"(";
Put(T->lchild);
if(T->rchild!=NULL)
{
cout<<",";
}
Put(T->rchild);
cout<<")";
}
}
}
void start()
{
printf ("1.键盘输入一组学生记录建立二叉排序树\n");
printf ("2.二叉排序树存盘\n");
printf ("3.由文件恢复内存的二叉排序树\n");
printf ("4.中序遍历二叉排序树\n");
printf ("5.求二叉排序树深度\n");
printf ("6.求二叉排序树的所有节点数和叶子节点数\n");
printf ("7.向二叉排序树插入一条学生记录\n");
printf ("8.从二叉排序树中删除一条学生记录\n");
printf ("9.从二叉排序树中查询一条学生记录\n");
printf ("10.以广义表的形式输出二叉排序树\n");
}
int main()
{
printf("二叉排序树系统\n");
int ch;
BiTree T=NULL;
while (1)
{
start();
printf("请输入操作序号:\n");
cin>>ch;
switch(ch)
{
case 1:
printf ("请输入学生个数\n");
int n;
cin>>n;
printf ("请输入学生信息\n");
for(int i=0; i<n; i++)
{
char s[6];
int x;
printf ("请输入学生学号\n");
cin>>s;
printf ("请输入学生成绩\n");
cin>>x;
Insert(T,s,x);
}
break;
case 2:
f_write(T);
break;
case 3:
f_read(T);
break;
case 4:
MidOrderTraverse(T);
break;
case 5:
cout<<"二叉树深度为"<<Depth(T)<<endl;
break;
case 6:
cout<<"二叉树结点数为"<<numbers(T)<<endl;
cout<<"二叉树叶子结点数为"<<count(T)<<endl;
break;
case 7:
char s[6];
int x;
printf ("请输入插入学生学号\n");
cin>>s;
printf ("请输入插入学生成绩\n");
cin>>x;
Insert(T,s,x);
break;
case 8:
printf ("请输入删除学生姓名\n");
char Del[6];
cin>>Del;
Delete(T,Search_Line(T,Del));
printf ("已删除\n");
break;
case 9:
printf ("请输入查找学生姓名\n");
char Sear[6];
cin>>Sear;
printf ("姓名为%s的同学成绩为%d\n",s,Search_Line(T,Sear));
break;
case 10:
Put(T);
break;
case 11:
printf ("即将推出系统\n");
Sleep(200);
exit(0);
default:
printf("输入序号有误,请重新输入\n");
break;
}
}
return 0;
}
/*
5
001 80
002 96
003 60
004 99
005 85
*/