用二叉树实现简单学生健康管理系统
学校课程最近有要求数据结构实验用二叉树实现一个简单的学生健康新消息管理系统,这里记录一下自己实现的方法,主要就是利用二叉搜索树的性质进行各项操作。代码比较简陋,可能有不完美的地方,实现是完全没问题的,下面给主要代码
- 头文件定义
#ifndef DINTREE_h
#define DINTREE_H
#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<assert.h>
#include<fstream>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef struct student
{
string age;
string name;
string num;
string bir;
string sex;
string body;
void input(){
cout << "请输入学生信息:" << endl;
cout << "请输入学生学号:";
cin >> num;
cout << "请输入学生姓名:";
cin >> name;
cout << "请输入学生年龄:";
cin >> age;
cout << "请输入学生性别:";
cin >> sex;
cout << "请输入学生出生日期:";
cin >> bir;
cout << "请输入学生身体状况:";
cin >> body;
}
};
template<class T>
struct BinTreeNode
{
T data;
BinTreeNode<T> *leftchild, *rightchild;
BinTreeNode() :leftchild(NULL), rightchild(NULL) {}
BinTreeNode(T x1, BinTreeNode<T> *l, BinTreeNode<T> *r) :data(x1), leftchild(l), rightchild(r) {}
};
template<class T>
class BinaryTree
{
public:
BinTreeNode<T> *root;
void destroy(BinTreeNode<T> *s);
public:
BinaryTree() :root(NULL) {}
~BinaryTree() { destroy(root); }
bool IsEmpty() {
return (root == NULL) ? true : false;
}
void CreateBinTree();
BinTreeNode<T>* insert(BinTreeNode<T> *current, student s);
void del();
void readf();
void writef();
void search(string s);
void PrintBTree(BinTreeNode<T> *current);
void setroot(BinTreeNode<T> *newroot)
{
root = newroot;
}
};
template<class T>
void BinaryTree<T>::CreateBinTree()
{
student s;
root = new BinTreeNode<T>;
s.input();//学生信息的输入函数
root->data = s;//初始化根的信息
cout << "是否要继续输入?“是”:请输入1,“否”:请输入0" << endl;
int k;
cin >> k;
while (k)
{
s.input();
root=insert(root, s);//根据搜索树的性质,按照学号的大小将学生信息插入搜索树中
cout << "是否要继续输入?“是”:请输入1,“否”:请输入0" << endl;
cin >> k;
}
}
template<class T>
BinTreeNode<T>* BinaryTree<T>::insert( BinTreeNode<T> *current,student s)
{
if (!current)//如果节点为空,表明找到了可插入的位置
{
current = new BinTreeNode<T>;//new一个节点,存储学生信息。
current->data = s;
current->leftchild = NULL;
current->rightchild = NULL;
}
else {
if (s.num > current->data.num)//如果学生学号大于当前结点的学号,插入当前结点的右边,把插入后的树作为当前结点的右节点
{
current->rightchild=insert(current->rightchild, s);
}
else if (s.num < current->data.num)//同理
{
current->leftchild=insert(current->leftchild, s);
}
}
return current;
}
template<class T>
void BinaryTree<T>::del()
{
cout << "请输入要删除的学生学号!";
string num1;
cin >> num1;
BinTreeNode<T> *p = root;
while (p->data.num != num1)//若是结点的学号不与要删除学生的学号匹配
{
if (p->data.num > num1)//若是节点学号大于要删除学生学号,在左子树中找
{
p = p->leftchild;
}
else if (p->data.num <num1)//同理
{
p = p->rightchild;
}
else if (p == NULL)//一直找找不到,报错
{
cout << "要查找的学生不存在" << endl;
return;
}
}
BinTreeNode<T> *z;
if (p->rightchild&&p->leftchild)//找到了但是有左右子树
{
z = p;
p = p->rightchild;
while (p->leftchild->leftchild != NULL)//找右子树中的最小学号的节点
{
p = p->leftchild;
}
z->data = p->leftchild->data;//把最小节点移到被删除节点,然后最小节点置空
p->leftchild = NULL;
}
else {
z = p;//如果只有左子树或右子树,就直接把下面整个子树移上来,删除匹配的节点
if (!p->leftchild)
{
p = p->rightchild;
}
else if (!p->rightchild)
{
p = p->leftchild;
}
delete z;
}
}
template<class T>
void BinaryTree<T> :: readf()//从文件中的读信息,插入,因为eof会多读一次,所以加了个条件
{
ifstream file("./1.txt");
student s;
while (true)
{
if (file.eof())
{
break;
}
file >> s.num;
file >> s.name;
file >> s.age;
file >> s.sex;
file >> s.bir;
file >> s.body;
if (s.num == "")
continue;
else {
root = insert(root, s);
}
}
}
template<class T>
void BinaryTree<T> ::writef()//写入
{
ofstream file2;
file2.open("./1.txt", ios::out);
student s;
int k = 1;
while (k)
{
s.input();
file2 << s.num << " " << s.name << " " << s.age << " " << s.sex << " " << s.bir << " " << s.body << endl;
cout << "是否要继续向文件写入?是:请输入“1”,否:请输入“0”" << endl;
cin >> k;
}
}
template<class T>
void BinaryTree<T>::search(string s)
{
BinTreeNode<T> *p;
p = root;
while (s != p->data.num)
{
if (p == NULL)//一直找到空节点,代表树中没有该学生的信息,报错
{
cout << "没有该学号学生信息!" << endl;
return;
}
else if (s > p->data.num)//查找原理其实和删除的原理一样,都是根据二叉搜索树的性质来查找,不多说了
{
p = p->rightchild;
}
else if (s < p->data.num)
{
p = p->leftchild;
}
}
cout << "查询信息如下:" << endl;
cout << "学生学号:";
cout << p->data.num<<endl;
cout << "学生姓名:";
cout << p->data.name << endl;
cout << "学生年龄:";
cout << p->data.age << endl;
cout << "学生性别:";
cout << p->data.sex << endl;
cout << "学生出生日期:";
cout << p->data.bir << endl;
cout << "学生身体状况:";
cout << p->data.body << endl;
}
template<class T>
void BinaryTree<T> ::PrintBTree(BinTreeNode<T> *current)//利用前序遍历从输出整个树
{
BinTreeNode<T> *p;
p = current;
if (p)
{
cout << "学生学号:";
cout << p->data.num << endl;
cout << "学生姓名:";
cout << p->data.name << endl;
cout << "学生年龄:";
cout << p->data.age << endl;
cout << "学生性别:";
cout << p->data.sex << endl;
cout << "学生出生日期:";
cout << p->data.bir << endl;
cout << "学生身体状况:";
cout << p->data.body << endl;
cout << endl;
PrintBTree(p->leftchild);
PrintBTree(p->rightchild);
}
}
template<class T>
void BinaryTree<T>::destroy(BinTreeNode<T> *subtree)
{
if (subtree != NULL)
{
destroy(subtree->leftchild);
destroy(subtree->rightchild);
delete subtree;
}
}
#endif // !DINTREE_h
2 源程序
#include"dintree.h"
using namespace std;
int main()
{
int i = 1;
student s;
string num3;
BinaryTree<student> s1;
while (i != 8)
{
cout << "---------------------------------------------------------" << endl;
cout << "1------新建学生健康表" << endl;
cout << "2------向学生健康表插入学生信息" << endl;
cout << "3------在健康表删除学生信息" << endl;
cout << "4------从文件中读取健康表信息" << endl;
cout << "5------向文件写入学生健康表信息" << endl;
cout << "6------在健康表中查询学生信息(按学生学号来进行查找)" << endl;
cout << "7------在屏幕中输出全部学生信息" << endl;
cout << "8------退出" << endl;
cout << "---------------------------------------------------------" << endl;
cin >> i;
switch (i)
{
case 1:s1.CreateBinTree();
break;
case 2:
s.input();
s1.root = s1.insert(s1.root, s);
cout << "插入完毕!" << endl;
break;
case 3:
s1.del();
break;
case 4:
s1.readf();
break;
case 5:
s1.writef();
break;
case 6:
cout << "请输入要查询学生的学号:" << endl;
cin >> num3;
s1.search(num3);
break;
case 7: cout << "全部学生信息如下:" << endl;
s1.PrintBTree(s1.root);
break;
case 8:
return 0;
break;
}
}
}