#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(A, B) ((A)>(B)?(A):(B))
#define Malloc(type) (type*)malloc(sizeof(type))
struct stu_grade
{
char stu_name[15];//姓名
float grade;//成绩
char number[15];//编号(学号)
};
typedef struct student_list
{
struct student_list* lchild;//左孩子
struct student_list* rchild;//右孩子
int height;
struct stu_grade perfor_info;//学生结构体类型的数据
}student_node;
void tree_for_each(student_node* root);//所有结点数据,递归
int get_tree_height(student_node* root);//得到二叉树高度,递归
void ui();//菜单提示信息
void menu(int choose);//根据输入决定程序去向
student_node* remove_tree_node(student_node* root, char rm_value[]);//删除节点 ,递归
student_node* request_student_node(stu_grade* value);//申请二叉树节点
student_node* tree_node_rotate_right(student_node* root);//左左不平衡
student_node* tree_node_rotate_left(student_node* root);//右右不平衡
student_node* tree_node_rotate_left_right(student_node* root);//左右不平衡
student_node* tree_node_rotate_right_left(student_node* root);//解决右左不平衡
student_node* insert_node_to_tree(student_node* root, student_node* new_node);//插入学生数据,递归
student_node* find_tree_node(student_node* root, char input_value[]);//查找节点 ,递归
char input_value[15];
stu_grade input_student_data;
student_node* root = NULL;
student_node* new_node, * find_node;
bool sign = false;//标记是否找到结点
int main()
{
int choose;
while (1)
{
sign = false;
system("cls");
ui();
scanf_s("%d", &choose);
menu(choose);
system("pause");
}
return 0;
}
int get_tree_height(student_node* root)
{
if (root == NULL) return 0;
return MAX(get_tree_height(root->lchild), get_tree_height(root->rchild)) + 1;//递归
}
student_node* request_student_node(stu_grade* value)
{
student_node* new_node;
new_node = Malloc(student_node);
if (new_node == NULL)
{
printf("没有申请到二叉树节点,学生系统异常\n");
return NULL;
}
if (value != NULL)
{
new_node->perfor_info = *value;
new_node->lchild = NULL;
new_node->rchild = NULL;
}
return new_node;
}
student_node* tree_node_rotate_right(student_node* root)//左左不平衡
{
student_node* tmp;
tmp = root->lchild;
root->lchild = tmp->rchild;
tmp->rchild = root;
tmp->height = get_tree_height(tmp);
root->height = get_tree_height(root);
return tmp;
}
student_node* tree_node_rotate_left(student_node* root)//右右不平衡
{
student_node* tmp;
tmp = root->rchild;
root->rchild = tmp->lchild;
tmp->lchild = root;
tmp->height = get_tree_height(tmp);
root->height = get_tree_height(root);
return tmp;
}
student_node* tree_node_rotate_left_right(student_node* root)//左右不平衡
{
root->lchild = tree_node_rotate_left(root->lchild);
root = tree_node_rotate_right(root);
return root;
}
student_node* tree_node_rotate_right_left(student_node* root)//右左不平衡
{
root->rchild = tree_node_rotate_right(root->rchild);
root = tree_node_rotate_left(root);
return root;
}
student_node* insert_node_to_tree(student_node* root, student_node* new_node)//插入学生数据
{
if (root == NULL) return new_node;
if (strcmp(root->perfor_info.number,new_node->perfor_info.number)>0) root->lchild = insert_node_to_tree(root->lchild, new_node);
else root->rchild = insert_node_to_tree(root->rchild, new_node);
if (get_tree_height(root->lchild) - get_tree_height(root->rchild) == 2)
{
if (strcmp(new_node->perfor_info.number,root->lchild->perfor_info.number)<0) root = tree_node_rotate_right(root);
else root = tree_node_rotate_left_right(root);
}
else if (get_tree_height(root->rchild) - get_tree_height(root->lchild) == 2)
{
if (strcmp(new_node->perfor_info.number,root->rchild->perfor_info.number)>=0)
{
root = tree_node_rotate_left(root);
}
else root = tree_node_rotate_right_left(root);
}
root->height = get_tree_height(root);
return root;
}
student_node* find_tree_node(student_node* root, char input_value[])//递归过程
{
if (root == NULL) return NULL;
if (strcmp(root->perfor_info.number,input_value)>0) return find_tree_node(root->lchild, input_value);
else if (strcmp(root->perfor_info.number,input_value)<0) return find_tree_node(root->rchild, input_value);
return root;
}
void tree_for_each(student_node* root)
{
if (root == NULL) return;
tree_for_each(root->lchild);
sign = true;
printf("编号:%s,学生姓名:%s,学生成绩:%.2f\n", root->perfor_info.number, root->perfor_info.stu_name, root->perfor_info.grade);
tree_for_each(root->rchild);
}
student_node* remove_tree_node(student_node* root, char rm_value[])
{
student_node* tmp;
if (root == NULL) return NULL;
if (strcmp(root->perfor_info.number,rm_value)==0)
{
if (root->lchild == NULL && root->rchild == NULL)
{
free(root);
return NULL;
}
else if (root->lchild != NULL)//如果有左子树
{
for (tmp = root->lchild; tmp->rchild != NULL; tmp = tmp->rchild);
strcpy_s(root->perfor_info.number, tmp->perfor_info.number);
root->lchild = remove_tree_node(root->lchild, tmp->perfor_info.number);
}
else//如果只有右子树
{
for (tmp = root->rchild; tmp->lchild != NULL; tmp = tmp->lchild);
strcpy_s(root->perfor_info.number, tmp->perfor_info.number);
root->rchild = remove_tree_node(root->rchild, tmp->perfor_info.number);
}
}
else if (strcmp(rm_value,root->perfor_info.number)<0)
{
root->lchild = remove_tree_node(root->lchild, rm_value);
}
else
{
root->rchild = remove_tree_node(root->rchild, rm_value);
}
if (get_tree_height(root->lchild) - get_tree_height(root->rchild) == 2)//左不平衡
{
if (get_tree_height(root->lchild->lchild) - get_tree_height(root->lchild->rchild) == 1)
{ //左左不平衡
root = tree_node_rotate_right(root);
}
else
{ //否则则是插入到root->lchild的右边去,出现了左右不平衡
root = tree_node_rotate_left_right(root);
}
}
else if (get_tree_height(root->rchild) - get_tree_height(root->lchild) == 2)//右不平衡
{
if (get_tree_height(root->rchild->rchild) - get_tree_height(root->rchild->lchild) == 1)//右右不平衡
{
root = tree_node_rotate_left(root);
}
else//右左不平衡
{
root = tree_node_rotate_right_left(root);
}
}
root->height = get_tree_height(root);
return root;
}
void ui()
{
printf("****************************************************\n");
printf("****************欢迎来到学生成绩管理系统************\n");
printf("****************请输入数字选择相应的指令************\n");
printf("*****************1、增加插入学生的成绩**************\n");
printf("*****************2、搜索学生成绩********************\n");
printf("*****************3、打印所有学生的成绩**************\n");
printf("*****************4、删除学生的成绩******************\n");
printf("*****************5、退出管理系统********************\n");
printf("****************************************************\n");
}
void menu(int choose)
{
switch (choose)
{
case 1: //创建一个新的二叉树
student_node * root3;
root3 = root;
printf("请您输入学生的编号:\n");
scanf_s("%s", input_student_data.number,15);
root3 = find_tree_node(root3, input_student_data.number);
if (root3 != NULL)
{
printf("这个学生已经存在于这个系统中\n");
break;
}
printf("请您输入学生的姓名:\n");
scanf_s("%s", input_student_data.stu_name,15);
printf("请您输入学生的成绩:\n");
scanf_s("%f", &input_student_data.grade);
new_node = request_student_node(&input_student_data);
root = insert_node_to_tree(root, new_node);
break;
case 2: //查找
printf("请输入学生的编号来查询学生成绩信息\n");
scanf_s("%s", &input_value,15);
find_node = find_tree_node(root, input_value);
if (find_node == NULL)
{
printf("找不到该学生的信息\n");
break;
}
printf("编号:%s,学生姓名:%s,学生成绩:%.2f\n", find_node->perfor_info.number, find_node->perfor_info.stu_name, find_node->perfor_info.grade);
break;
case 3: //输出所有节点信息
printf("所有的学生的成绩信息为\n");
tree_for_each(root);
if (sign == false) printf("系统中没有学生的信息\n");
break;
case 4: //删除一个节点信息
student_node * root2;
root2 = root;
printf("请输入学生的编号来删除学生成绩信息\n");
scanf_s("%s", &input_value,15);
root2 = find_tree_node(root2, input_value);
if (root2 == NULL)
{
printf("错误:没有找到这个学生:%.2f\n", input_value);
break;
}
root = remove_tree_node(root, input_value);
break;
case 5: //退出系统
exit(0);
}
}
编译器:VS2019