基于二叉平衡树的学生信息管理系统
二叉平衡树的插入,删除函数参考了这位大佬的代码
详见 https://www.cnblogs.com/sench/p/7786718.html添加链接描述
对函数进行了一点改进
注意:本程序中的二叉平衡树的lr旋转函数、rl旋转函数与网上博客名字相反(比如网上是lr,本程序是rl,内容一致)!!!
运行界面:
头文件:
typedef struct stu
{unsigned long long num; //学号char name[9]; // 字符串结束符 勿忘 !!!int sex; //性别unsigned int age;char major[15]; //专业}student;
typedef struct node
{DataType data; // #define DataType studentstruct node* leftson;struct node* rightson;
}shu;
int zhao(shu* root, unsigned long long x);
//int cha(shu** root, DataType x);
int shanshu(shu** root, unsigned long long x);
int shanshugen(shu** root, unsigned long long x);
shu* minshu(shu* root);
shu* maxshu(shu* root);int getmax(int a, int b) //比较大小,返回较大值
{if (a >= b)return a;elsereturn b;
}
int gaodu(shu* root) // 求该节点的高度
{if (root == 0)return -1;return (getmax(gaodu(root->leftson), gaodu(root->rightson)) + 1);
}
shu* ll(shu* p) // 左左
{shu* t = p->leftson;if (t != 0) // lr 时只需 rr {p->leftson = t->rightson;t->rightson = p;}else{}return t;
}shu* rr(shu* p) // 右右
{shu* t = p->rightson;if (t != 0){p->rightson = t->leftson;t->leftson = p;}else{}return t;
}
shu* lr(shu* p) // 左右 // 网上都是rl
{p->rightson = ll(p->rightson);shu* t = rr(p);return t;
}
shu* rl(shu* p) // 右左
{p->leftson = rr(p->leftson);shu* t = ll(p);return t;
}
int chaping(shu** root, DataType x) // 二叉 平衡 树的插入 递归 插入成功返回1,失败返回0
{if (*root == 0){(*root) = (shu*)malloc(sizeof(shu));(*root)->data = x;(*root)->leftson = (*root)->rightson = 0;}elseif (x.num < (*root)->data.num ) // 进入左子树{chaping(&((*root)->leftson), x);if (gaodu((*root)->leftson) - gaodu((*root)->rightson) == 2) // 判断二叉树是否 失衡 (因插入)// 此 if 语句可用于使失衡的二叉树平衡{if (gaodu((*root)->leftson->leftson) >= gaodu((*root)->leftson->rightson)){ // == 在因插入失衡看来,不可能出现==情况*root = ll(*root);}else*root = rl(*root); //注意本程序 rl 与网上 lr 内容一致 ,名字相反}}elseif (x .num > (*root)->data.num ) // 进入右子树{chaping(&((*root)->rightson), x);if (gaodu((*root)->leftson) - gaodu((*root)->rightson) == -2){if (gaodu((*root)->rightson ->leftson) <= gaodu((*root)->rightson ->rightson))*root = rr(*root);else*root = lr(*root);}}else //== 树中已有该关键字,插入失败{return 0;}return 1;
}
int shanping(shu** root, unsigned long long x) // 二叉 平衡 树的删除(结点) 删除成功返回1,失败返回0
{if (root == 0) // 说明 树中 无 该关键字 对树不进行任何操作return 0;elseif (x < (*root)->data.num ) // 进入左子树{shanping(&((*root)->leftson), x);if (gaodu((*root)->leftson) - gaodu((*root)->rightson) == -2) // 判断二叉树是否 失衡 (因删除){ // 此 if 语句可用于使失衡的二叉树平衡if (gaodu((*root)->rightson->leftson) <= gaodu((*root)->rightson->rightson)){ //==在因删除失衡看来,可以出现==情况*root = rr(*root);}else*root = lr(*root); //注意本程序 rl 与网上 lr 内容一致 ,名字相反}}elseif (x > (*root)->data.num ) // 进入右子树{shanping(&((*root)->rightson), x);if (gaodu((*root)->leftson) - gaodu((*root)->rightson) == 2){if (gaodu((*root)->leftson->leftson) >= gaodu((*root)->leftson->rightson))*root = ll(*root);else*root = rl(*root);}}else //== 树中找到该关键字,开始删除{shanshu(root, x ); // 不用担心效率,root是当前找到的结点,可以说在shanshu函数 一开始就会找到}return 1;
}
int zhao(shu* root, unsigned long long x) // 二叉 排序 树的查找,循环方法 找到返回1,没找到或空树 返回0
{if (root == 0){return 0;}shu* p = root;while (p != 0){if (p->data.num == x){//cout<<p->data .num printf("学号%lld 姓名%s 性别", p->data.num, p->data.name);if (p->data.sex == 0)cout << "女";elsecout << "男";printf(" 年龄%d 专业%s\n", p->data.age, p->data.major);return 1;}if (p->data.num > x)p = p->leftson;elsep = p->rightson;}return 0;
}int shanshugen(shu** root, unsigned long long x) // 专门用于二叉排序树的 根结点 的删除 因为删除根节点,需要改变*root
{shu* p = (*root);if (p->data.num != x){cout << "根节点的值与所找的结点值不同";return 0;}if (p->leftson == 0 && p->rightson == 0) //被删除结点 无孩子结点{free(p);(*root) = 0;}else if (p->leftson != 0 && p->rightson == 0) //被删除结点只有 左孩子结点{(*root) = p->leftson;free(p);}else if (p->leftson == 0 && p->rightson != 0) //被删除结点只有 右孩子结点{(*root) = p->rightson;free(p);}else //被删除结点 左右孩子结点 都有 {shu* curr = p; // 以下代码 1均复制粘贴于 shanshu 函数的被删除结点 左右孩子结点 都有的情况代码// 2下面两种情况均不会删除 二叉树本身的根结点 也就是说 *(*root)不用改变if (curr->rightson->leftson == 0){shu* q = curr->rightson;curr->data = curr->rightson->data;curr->rightson = curr->rightson->rightson;free(q);}else{curr->data = curr->rightson->leftson->data;shanshu(&curr->rightson, curr->data.num);}}return 1;
}
int shanshu(shu** root, unsigned long long x) // 二叉 排序 树的删除(结点) 空树或未找到该结点return 0 找到该结点并删除return 1
{int tag = 0;shu* curr = *root;shu* parent = 0;while (curr != 0){if (curr->data.num == x){tag = 1; //说明找到了 应被删除的结点break;}parent = curr;if (curr->data.num > x)curr = curr->leftson;elsecurr = curr->rightson;}if (tag == 0)return 0;if (parent == 0) //被删除的结点是 根结点 {shanshugen(root, x); // 调用专门删除 根节点 函数}else{if (curr->leftson == 0 && curr->rightson == 0) //被删除结点 无孩子结点 //警告没用{if (parent->leftson == curr){parent->leftson = 0;}elseparent->rightson = 0;free(curr);}elseif (curr->leftson != 0 && curr->rightson == 0) //被删除结点只有 左孩子结点{if (parent->leftson == curr){parent->leftson = curr->leftson;}elseparent->rightson = curr->leftson;free(curr);}elseif (curr->leftson == 0 && curr->rightson != 0) //被删除结点只有 右孩子结点{if (parent->leftson == curr){parent->leftson = curr->rightson;}elseparent->rightson = curr->rightson;free(curr);}else //被删除结点 左右孩子结点都有{if (gaodu(curr->rightson) - gaodu(curr->leftson) >= 0) //右子树高度 > =左子树 这样可以尽可能的使二叉树平衡{shu* w = minshu(curr->rightson);curr->data = w->data;shanshu(&w, w->data.num);}else // 右子树高度 < 左子树{shu* w = maxshu(curr->leftson);curr->data = w->data;shanshu(&w, w->data.num);}/*if (curr->rightson->leftson == 0) // 课本way 有风险{shu* q = curr->rightson;curr->data = curr->rightson->data;curr->rightson = curr->rightson->rightson;free(q);}else{curr->data = curr->rightson->leftson->data;shanshu(&curr->rightson, curr->data.num);}*/}}return 1;
}
shu* minshu(shu* root) // 求该二叉排序树的最 小 值结点,返回结点地址
{shu* p = root;if (root == 0){cout << "空树无最小结点" << endl;return 0;}while (p->leftson != 0){p = p->leftson;}return p;
}
shu* maxshu(shu* root) // 求该二叉排序树的最 大 值结点,返回结点地址
{shu* p = root;if (root == 0){cout << "空树无最大结点" << endl;return 0;}while (p->rightson != 0){p = p->rightson;}return p;
}
int qianxusum(shu* q) //计算二叉树的结点总数
{int sum = 0;if (q != 0){sum += 1;sum += (qianxusum(q->leftson) + qianxusum(q->rightson));}return sum;}
int xiaohui(shu** p) //二叉树的销毁
{if (p == 0){cout << "当前结点为空,无法销毁" << endl;return -1;}if ((*p)->leftson != 0){xiaohui(&(*p)->leftson);}if ((*p)->rightson != 0){xiaohui(&(*p)->rightson);}free(*p);*p = 0;return 1;
}
void wen(shu* x)
{printf("%d ", x->data);
}
void dayin(shu* q, int n)
{if (q != 0){n++;dayin(q->rightson, n);for (int i = 0; i < n; i++)printf(" ");wen(q);printf("\n");dayin(q->leftson, n);}}
源文件:
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<malloc.h>
#pragma warning(disable:4996)
#define maxsize 100
#define DataType student
using namespace std;
#include <malloc.h>
#include"标头.h"
void show()
{int tag = 0; // tag=0 循环 =1结束循环shu* root = 0;do{//***********显示提示信息********** printf(" 学生信息管理系统 \n");printf(" \n");printf(" 1.插入学生信息 2.删除学生信息 \n"); //显示序号1的功能 printf(" \n"); //显示序号2的功能 printf(" 3.查询学生信息 4.打印二叉树 \n"); //显示序号3的功能 printf(" \n"); //显示序号4的功能 printf(" 0.退出系统 \n"); //显示序号5的功能 printf(" \n"); //显示序号6的功能 printf("请输入功能序号: "); //提示用户输入 int n;scanf("%d", &n);while ((n < 0 || n > 4)) //对用户输入不能实现的功能序号进行处理 {printf(" 抱歉,没有此功能,请重新输入功能序号: "); //提示用户所输入的功能序号系统不能进行处理 rewind(stdin);while (!scanf("%d", &n)) //接收用户重新输入的功能序号 {printf(" 输入序号有误,请重新输入: ");rewind(stdin);}printf("\n"); //输出回车 }switch (n){case 0:tag = 1;break;case 1: int sum2; // a2插入学生信息 //shu* root = 0;int p;p = 0;printf("请输入所要插入的学生总数\n");scanf("%d", &sum2);student a2;printf("学号 姓名 性别(1是男 0是女) 年龄 专业\n");printf("请输入以上信息\n");for (int i = 0; i < sum2; i++){while (5 != scanf("%lld %s %d %d %s", &a2.num, a2.name, &a2.sex, &a2.age, a2.major)|| a2.age < 0 || a2.age > 30 || (a2.sex != 0 && a2.sex != 1)){printf("输入有误,请选择 (1)重新输入;(2)重新选择功能\n");rewind(stdin);scanf("%d", &p);if (p == 2) break;}rewind(stdin);while (chaping(&root, a2) == 0) //插入函数 {printf("学号输入重复,请选择 (1)重新输入;(2)重新选择功能\n");rewind(stdin);scanf("%d", &p);if (p == 2) break;while (scanf("%lld ", &a2.num) != 1){printf("学号输入有误,请选择 (1)重新输入;(2)重新选择功能\n");rewind(stdin);scanf("%d", &p);if (p == 2) break;}}rewind(stdin);if (p != 2)printf("插入学生信息成功!\n");}break;case 2:unsigned long long num3; // 删除学生信息int sum3;int o;o = 0;//shu* root = 0;printf("请输入所要删除的学生总数\n");//printf("请输入所要删除的学生学号\n");while (0 == scanf("%d", &sum3) || qianxusum(root) < sum3){printf("总数过多或有误,请选择重新输入 \n");rewind(stdin);}printf("请输入所要删除的学生学号\n");for (int i = 0; i < sum3; i++){while (0 == scanf("%lld", &num3) || shanping(&root, num3) == 0) //删除函数 {printf("学号输入不存在或有误,请选择 (1)重新输入(只输入学号即可);(2)重新选择功能 \n");rewind(stdin);scanf("%d", &o);if (o == 2) break;rewind(stdin);}rewind(stdin);if (o != 2) printf("删除学生信息成功!\n");}break;case 3:unsigned long long num4; //查询学生信息int sum4;int r;r = 0;//shu* root = 0;printf("请输入所要查找的学生总数\n");//printf("请输入所要查找的学生学号\n");while (0 == scanf("%d", &sum4) || qianxusum(root) < sum4){printf("总数过多或有误,请选择重新输入 \n");rewind(stdin);}printf("请输入所要查找的学生学号\n");for (int i = 0; i < sum4; i++){while (0 == scanf("%lld", &num4) || zhao(root, num4) == 0) //查找函数 {printf("学号不存在或有误,请选择 (1)重新输入(只输入学号即可);(2)重新选择功能\n");rewind(stdin);scanf("%d", &r);if (r == 2) break;}rewind(stdin);}break;case 4:dayin(root, 0);break;}} while (tag == 0);}int main()
{show();return 1;}
基于二叉平衡树的学生信息管理系统相关推荐
- py222基于python+django的高校学生信息管理系统
开发语言:Python 编号:py222基于python+django的高校学生信息管理系统#毕业设计 python框架:django 软件版本:python3.7/python3.8 数据库:mys ...
- (解析+源码)基于JAVA Swing+MySQL实现学生信息管理系统(增、删、改、查)数据库/文件存储
根据学校对学生信息日常管理需要,学生信息管理系统包括以下功能: 登录系统: 新建学生信息:添加学生信息: 删除学生信息:对指定学生信息进行删除: 修改学生信息:对指定学生信息进行修改 查找学生信息:输 ...
- 基于python的师生一体化学生信息管理系统——python期末设计!!!
系统介绍 该系统使用python语言进行程序设计,设计的主要内容可概括为以下几点:师生一体化学生信息管理系统,首先由管理员(教师)增加.删除.修改.查找.导出学生信息(excel表格的形式),再有学生 ...
- 基于Java Swing+mysql的学生信息管理系统
学生信息管理系统 学生管理系统目录 学生信息管理系统 一.前期工作 ①下载eclipse.mysql.navicat ②建立navicat与mysql的连接 二.明确项目的具体实现思路 ★系统功能分析 ...
- 基于JAVA实现的简易学生信息管理系统(附源码)
一.前言 最近在学习JAVA,这几天跟着网上的视频学完基础知识之后,做了一个学生信息管理系统,写的比较普通,没太大亮点,希望可以给初学者一些参考经验,另外,如有不恰当的地方还请各位指正! 学生信息管理 ...
- 基于JAVA+SpringMVC+MYSQL的学生信息管理系统
项目功能: 々. 这个程序可以允许管理员创建新用户和删除旧用户. 々. 管理员可以查看所有用户的具体信息,例如姓名,电话,家庭住址,家长电话. 々. 如果学生外出,管理员可以对这些外出学生进行编辑.可 ...
- HTML期末作业-基于HTML+CSS+JavaScript制作学生信息管理系统模板
- 基于C语言的学生信息管理系统_(更新版)_(附源码和安装包)_课程设计_☆*往事随風*☆的博客
学生信息管理系统 一.需求 基于C语言编写一个学生信息管理系统来实现对学生成绩的管理(数学.C语言.英语),系统要能够实现基本的增.删.改.查等功能,在此基础上还可以自由发挥,要求使用到数组.文件.排 ...
- 嘉明SSM学习之基于SSM框架的学生信息管理系统
项目的github:https://github.com/zjm-cityboy/sims-GitHub.git 可以的话点个小星星嘿嘿 1.项目介绍 1.1.项目环境配置 操作系统:Windows1 ...
最新文章
- TED+如何让压力成为朋友+如何面对压力决定你的未来
- 【LeetCode】最大子序和
- cacti中监控squid的方法
- bo dto java vo_java中PO、VO、BO、POJO、DAO、DTO、TO、QO、Bean、conn的理解
- oracle数据字典表与视图
- 《Head first设计模式》学习笔记 – 迭代器模式
- python网络信息提取_Python网络爬虫与信息提取入门13
- Discuz论坛架设从零起步之二
- Android Json 解析
- ios - Parse Issues in NSObjCRuntime, NSZone, and NSObject
- springboot 工程启动报错之Consider defining a bean of type ‘XXX’ in your configuration.
- 2699元起!格力首款5G手机悄然上架:骁龙765G处理器
- 外参矩阵转四元数,左右手坐标系转化1
- linux下curl安装报错symbol lookup error
- 网页导出pdf不完整_又一种pdf文献全文一键免费翻译的方法
- python平安夜代码加文案
- 牛客错题集C++(一)
- JDBC连接MySQL数据库的问题
- ubuntu NVIDIA CC sanity check failed:
- 苹果android怎么设置,iphone小圆点怎么设置调出来 自定义手势怎么用
热门文章
- 研究方法 | SCI 必备:3 款强大的英文论文写作神器
- MICK-SQL基础教程(第二版) 第八章 SQL高级处理
- JS——遍历数组方法总结
- 微信小程序如何发红包
- Redis6 系列三 配置文件介绍
- 2023中国重庆大数据及云计算展览会
- 如何卸载linux上的jdk1.7,RedHat卸载JDK 1.7并安装JDK1.8
- Linux 运行jar包命令
- c语言的除法向上还是向下取整,【向上取整/向下取整】C語言向上或向下取整 函數...
- WPS一级计算机基础知识,2017年一级计算机基础及WPS Office考试大纲