有一批学生信息,存储在文件stuinfo.txt中,学生信息的格式为:
(学号(12位,关键字项)、姓名、性别、班级、手机号(11位))
设计程序,要求实现下面功能:
(1)根据文件中的学生信息,生成一棵二叉排序树(同时保证是一棵AVL
树)。
(2)对二叉排序树作先序、中序和后序遍历并输出遍历结果(同时输出每
个结点的平衡因子)。
(3)查询二叉排序树中是否存在给定记录(按学号查询),并输出查询结
果,若不存在该记录,则插入该结点(数据的变化要反映到文件中,
插入和删除结点后仍要保证是一棵平衡二叉树)。
(4)删除指定学生记录(按学号删)。
(5)计算并输出该平衡二叉树的平均查找长度。
代码示例
#include<iostream>
#include<sstream>
#include<fstream>
#include<bits/stdc++.h>
#define N 10
using namespace std;
typedef struct up{
char num[20];//学号
char name[20];//姓名
char sex[20];//性别
char clas[20];//班级
char number[20];//电话号码
}student;
//二叉树
typedef struct BstNode{
student data;
int bf;//节点的平衡因子
struct BstNode *lchild;
struct BstNode *rchild;
}BSTNode,*BSTree;
//线性表
typedef struct{
student* elem;
int length;
}SqList;
void InitList(SqList &L){
L.elem =new student[N];
L.length =0;
}
//将文件中学生信息存储到线性表中
void ReadData(SqList &str){
int i=0;
InitList(str);
ifstream infile("C:\\Users\\郭顺志\\Desktop\\stuinfo.txt");//以输入的方式(读文件的方式)打开文件C:\\Users\\郭顺志\\Desktop\\stuinfo.txt
while(!infile.eof()) //只要文件没读完,就读一行数据到顺序表L中的第i个分量中
{
infile>>str.elem [i].num; // 读一行中的学号信息,放入L.elem[i].num
infile>>str.elem [i].name; // 读一行中的书名信息,放入L.elem[i].name
infile>>str.elem [i].sex;// 读一行中的价格信息,放入L.elem[i].sex
infile>>str.elem [i].clas;// 读一行中的价格信息,放入L.elem[i].clas
infile>>str.elem [i].number;// 读一行中的价格信息,放入L.elem[i].number
i++;
}
str.length =i; //修改顺序表L的长度
infile.close(); //关闭文件
system("pause");
}
/* 对以p为根的二叉排序树作右旋处理, */
/* 处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点 */
void R_Rotate(BSTree* P)
{
BSTree L;
L = (*P)->lchild; /* L指向P的左子树根结点 */
(*P)->lchild = L->rchild; /* L的右子树挂接为P的左子树 */
L->rchild = (*P);
*P = L; /* P指向新的根结点 */
}
/* 对以P为根的二叉排序树作左旋处理, */
/* 处理之后P指向新的树根结点,即旋转处理之前的右子树的根结点0 */
void L_Rotate(BSTree* P)
{
BSTree R;
R = (*P)->rchild; /* R指向P的右子树根结点 */
(*P)->rchild = R->lchild; /* R的左子树挂接为P的右子树 */
R->lchild = (*P);
*P = R; /* P指向新的根结点 */
}
/* 对以指针T所指结点为根的二叉树作左平衡旋转处理 */
/* 本算法结束时,指针T指向新的根结点 */
void LeftBalance(BSTree* T)
{
BSTree L, Lr;
L = (*T)->lchild; /* L指向T的左子树根结点 */
switch (L->bf)
{ /* 检查T的左子树的平衡度,并作相应平衡处理 */
case 1: /* 新结点插入在T的左孩子的左子树上,要作单右旋处理 */
(*T)->bf = L->bf =0;
R_Rotate(T);
break;
case -1: /* 新结点插入在T的左孩子的右子树上,要作双旋处理 */
Lr = L-&