学生管理系统的设计与实现(c语言版本数据结构)

学生管理系统的设计与实现

文章目录

  • 学生管理系统的设计与实现
    • 1、需求分析
      • 1.1 实验目的:
      • 1.2 实验内容:
      • 1.3实验要求:
      • 1.4概要设计:
    • 2、概要设计
      • 2.1所用数据结构的定义及其相关说明(相关结构体或类的定义及其含义)
      • 2.2、各子程序调用关系
      • 2.3、各程序模块之间的层次(调用)关系
    • 3、详细设计,实现方法、实验结果及结论分析等:
      • 3.1 、memu (菜单选项)
      • 3.2、 输入学生信息
      • 3.3、打印学生信息
      • 3.4 插入学生信息到表
      • 3.5、删除学生信息
      • 3.6 、统计学生总数
      • 3.7、按姓名直接插入排序
      • 3.8 、按姓名折半插入排序
      • 3.9、按学号快速排序
      • 3.10、 递归调用对左子表排序
      • 3.11、按姓名折半查找(递归)
      • 3.12、按学号进行折半查找(非递归)
      • 3.13、main()
      • 3.14、主要功能算法的时间复杂度
    • 4、测试分析
      • 4.1、解决问题方法以及对设计与实现的回顾讨论和分析:
      • 4.2、经验和体会
      • 4.3、算法的时空分析
      • 4.4、测试和功能展示
        • 4.4.1、学生管理系统的建立
        • 4.4.2、显示学生信息
        • 4.4.3、插入学生信息
        • 4.4.4、删除学生信息
        • 4.4.5、统计表中学生人数
        • 4.4.6、利用直接插入排序按姓名进行排序
        • 4.4.7、利用折半插入排序按姓名进行排序
        • 4.4.8、利用快速排序按学号进行排序
        • 4.4.9、根据姓名进行折半查找,成功返回此学生的学号和成绩
        • 4.4.10、根据学号进行折半查找,成功返回此学生的姓名和成绩
    • 5、源程序清单(源程序清单是带详细注释的源程序)
    • 6、用户使用手册

1、需求分析

1.1 实验目的:

1.掌握重要的排序算法――直接插入排序和快速排序;

2.掌握折半查找算法。

3.综合运用所学数据结构知识,提高解决实际问题的能力。。

1.2 实验内容:

设计并实现一个学生管理系统,即定义一个包含学生信息(学号,姓名,成绩)的的顺序表

可以不考虑重名的情况,系统至少包含以下功能:

(1) 根据指定学生个数,逐个输入学生信息;

(2) 逐个显示学生表中所有学生的相关信息;

(3) 给定一个学生信息,插入到表中指定的位置;

(4) 删除指定位置的学生记录;

(5) 统计表中学生个数;

(6) 利用直接插入排序或者折半插入排序按照姓名进行排序;

(7) 利用快速排序按照学号进行排序;

(8) 根据姓名进行折半查找,要求使用递归算法实现,成功返回此学生的学号和成绩;

(9) 根据学号进行折半查找,要求使用非递归算法实现,成功返回此学生的姓名和成绩。

1.3实验要求:

(1)程序要添加适当的注释,程序的书写要采用缩进格式

(2程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。

(3)程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。

(4)根据实验报告模板详细书写实验报告

1.4概要设计:

(1)输入的形式和输入值的范围:输入对应的数字会选择不同的结果和不同的成绩;

(2)输出的形式:以对应的数字输出;

(3)程序所能达到的功能:所有的功能都实现了;

(4)测试数据:包括正确的输入及其输出结果和含有错误的输入及其输出结果。

2、概要设计

2.1所用数据结构的定义及其相关说明(相关结构体或类的定义及其含义)

#define ERROR 0     //用于返回错误
#define OK 1        //用于返回正确
#define SIZE 100    //定义stduent的大小
typedef int Status;  

学生管理系统的设计与实现(c语言版本数据结构)_第1张图片

1void menu()//选择菜单函数 2)Status InitList_Sq(SqList &L,int n)//新建学生数据3)Status Display_Sq(SqList L)//显示学生所有数据4)Status Insert_Sq(SqList &L,int n)//在顺序表L中第i个位置插入新的元素e5)Status Delete_Sq(SqList &L,int n)//在顺序表L中删除第i个元素6)Status GetLen_Sq(SqList &L)    //统计学生总数7void InsertSort(SqList &L)//姓名排序操作函数8void InsertSort(ElemType a[])//此处为直接插入排序。对姓名排序9int Search_Bin(SqList &L,char *s,int low,int high)//此处为折半插入排序。对姓名排序10int Partition(SqList &L,int low,int high)//利用快速排序按照学号进行排序11void QSort(SqList &L,int low,int high)12int Search_Bin(ElemType a[],char *key,int low,int high)//折半查找,递归方法13int Non_Search_Bin(ElemType a[],int key)//14int main()//主函数

2.2、各子程序调用关系

学生管理系统的设计与实现(c语言版本数据结构)_第2张图片

2.3、各程序模块之间的层次(调用)关系

学生管理系统的设计与实现(c语言版本数据结构)_第3张图片

3、详细设计,实现方法、实验结果及结论分析等:

自定义函数的名称及其功能说明

3.1 、memu (菜单选项)

void memu(void)
{
	printf("\t\t||************ 欢迎使用学生信息管理系统!****************||\n");
	printf("\t\t||**name:yuan number:xxxxxx    电信xxxx   *******     ||\n");
	printf("\t\t||   *********************************                ||\n");
    printf("\t\t||   *           功能菜单          *                   ||\n");
    printf("\t\t||   *********************************                ||\n");
	printf("\t\t||   1.输入学生信息                                     ||\n");
	printf("\t\t||   2.逐个显示学生的相关信息                            ||\n");
	printf("\t\t||   3.插入学生信息到指定位置                            ||\n");
	printf("\t\t||   4.删除指定位置的学生记录                            ||\n");
    printf("\t\t||   5.统计表中学生人数                                 ||\n");
	printf("\t\t||   6.利用直接插入排序按姓名进行排序                     ||\n");
	printf("\t\t||   7.利用折半插入排序按姓名进行排序                     ||\n");
	printf("\t\t||   8.利用快速排序按学号进行排序                         ||\n");
	printf("\t\t||   9.根据姓名进行折半查找,成功返回此学生的学号和成绩      ||\n");
	printf("\t\t||  10.根据学号进行折半查找,成功返回此学生的姓名和成绩      ||\n");
	printf("\t\t||  11.退出系统\n");
	printf("\t\t>>>请选择您需要的服务(1--11):");
}

3.2、 输入学生信息

Status InitList_Sq(SqList &L,int n)
{
	int i;
    L.elem=new Student[SIZE];
	L.length=1;		       //留下L.elem[0]作为哨兵
    //输入学生信息
	printf("\t\t请按顺序输入学生学号,姓名,成绩,不同项之间用Tab隔开:\n");
    printf("\t\t学号	姓名    成绩	\n");
    for(i=1;i<=n;i++)  	//输入学生信息
    {
		L.length++;     //表的长度加一
        printf("\t\t");
        scanf("%s %s %f", L.elem[i].no, L.elem[i].name,&L.elem[i].score);
		printf("\n");
    }
    printf("\t\t提示:成绩存入完毕!\n\n");
    printf("\t\t\t------请继续--------\n");
	return OK;
}

3.3、打印学生信息

Status Display_Sq(SqList L)
{	
	printf("\t\t位置\t学号\t姓名\t成绩\n");
	for(int j= 1; j<L.length; j++)
    {
        printf("\t\t%d\t%s\t%s\t %.2f\t\t\n\n",j, L.elem[j].no, L.elem[j].name, L.elem[j].score);
	}
	return OK;
}

3.4 插入学生信息到表

Status Insert_Sq(SqList &L,int n)
{	
	if(L.length==SIZE)			//考虑表中空间已满的情况
	{
		printf("\t\t操作失败,系统空间已满\n");
		return ERROR;
	}
	if(n<1||n>L.length)
	{			
		printf("\t\t操作失败,您要插入的位置不存在!\n");
		return ERROR;
	}
	for(int i=L.length-1;i>=n;i--)
		L.elem[i+1]=L.elem[i];		//依次将各学生的信息赋给其下一个位置
	printf("\t\t>>>输入要插入的学生信息:\n");
	printf("\t\t>>>学号:");
	scanf("%s",L.elem[n].no);
	printf("\n");
	printf("\t\t>>>姓名");
	scanf("%s",L.elem[n].name);
	printf("\n");
	printf("\t\t>>>成绩:");
	scanf("%f",&L.elem[n].score);
	printf("\n");
	L.length++;			//表长增加1
	printf("\t\t插入学生信息成功!\n");
	return OK;
}

3.5、删除学生信息

Status Delete_Sq(SqList &L,int n)
{
	if(n<1||n>L.length){
		printf("\t\t操作失败,您要删除的位置不存在!\n");
		return ERROR;
	}
	for(int i=n;i<=L.length-1;i++)
		L.elem[i]=L.elem[i+1];			//依次将各学生的信息赋给其上一个位置
	L.length--;							//表长减少1
	printf("\t\t删除学生信息成功!\n");
	return OK;
}

3.6 、统计学生总数

Status GetLen_Sq(SqList &L)
{
 
	printf("\t\t-----学生个数=-----\n");
    printf("%d",L.length-1);
	return OK;
}

3.7、按姓名直接插入排序

void InsertSort(SqList &L)
{
	int i,j;
    for(i=2;i<L.length;++i)
     if(strcmp(L.elem[i].name,L.elem[i-1].name)==-1)
       {
		 L.elem[0]=L.elem[i]; // 复制为哨兵
         L.elem[i]=L.elem[i-1];
         for(j=i-2;strcmp(L.elem[0].name,L.elem[j].name)==-1;--j)
	            L.elem[j+1]=L.elem[j]; // 记录后移 
         L.elem[j+1]=L.elem[0]; //插入到正确位置
       }
 }

3.8 、按姓名折半插入排序

Status BInsertSort (SqList &L)
{ 
	int low,high,m;		
	for(int i=2;i<L.length;++i){  
		L.elem[0]=L.elem[i];	// 复制为哨兵
		low=1;
		high=i-1;
		while(low<=high){	//利用折半方法找到插入位置	
			m=(low+high)/2; 
            if(strcmp(L.elem[0].name,L.elem[m].name)<0)
				high=m-1;
            else
				low=m+1; 
           }
		for(int j=i-1;j>=high+1;--j)	//纪录后移
			L.elem[j+1]=L.elem[j];
			L.elem[high+1]=L.elem[0];
    }
	return OK;
}

3.9、按学号快速排序

int pivotloc;
char pivotkey[10];
int Partition(SqList &L,int low,int high)
{
	L.elem[0]=L.elem[low];
	strcpy(pivotkey,L.elem[low].no);
	while(low<high)
	{
		while(low<high&&strcmp(L.elem[high].no,pivotkey)>=0)
	   //若有比哨兵小的high,则将其赋给low,否则high前移
			--high;
		L.elem[low]=L.elem[high];
		while(low<high&&strcmp(L.elem[low].no,pivotkey)<=0)	
		//若有比哨兵大的low,则将其赋给high,否则low后移
			++low;
		L.elem[high]=L.elem[low];
	}
    L.elem[low]=L.elem[0]; 
    return low;
}

3.10、 递归调用对左子表排序

 void QSort(SqList &L,int low,int high)
{
	  if(low<high)
	  {
		 pivotloc=Partition(L,low,high);		
         QSort(L,low,pivotloc-1);	//递归调用对左子表排序
         QSort(L,pivotloc+1,high);	//递归调用对右子表排序
       }
}

3.11、按姓名折半查找(递归)

int Search_Bin(SqList &L,char *s,int low,int high)
{
	int m;
	if(low<=high)
	{
		m=(low+high)/2;
		if(strcmp(s,L.elem[m].name)==0)
			return m;
		else if(strcmp(s,L.elem[m].name)<0)
			return Search_Bin(L,s,low,m-1);		//对左子表折半查找
		else
			return Search_Bin(L,s,m+1,high);	//对右子表折半查找
	}
	return -1;
}

3.12、按学号进行折半查找(非递归)

int Search_Bin1(SqList &L,char *s)
{
	int m,low=1,high=L.length-1;
	while(low<=high)
	{
		m=(low+high)/2;
		if(strcmp(s,L.elem[m].no)==0)
			return m;
		else if(strcmp(s,L.elem[m].no)<0)
			high=m-1;
		else
			low=m+1;
	}
	return -1;
}

3.13、main()

int main(void)
{
	int no;
	int n;
	char names[20],nos[10];
	SqList L;
	L.length=1;
	while(1)
	{

		memu();
		scanf("%d",&no);
		printf("\n");
		switch(no)
		{
            //输入学生信息
			case 1:  
				printf("\t\t>>>请输入学生个数:");
				scanf("%d",&n);
				InitList_Sq(L,n);
				break;
            //逐个显示学生的相关信息
			case 2:
				if(L.length==1)
				{								//判断表是否为空
					printf("\t\t学生表为空,无可显示的学生信息!\n");
					break;
				}
				printf("\t\t>>>输出学生信息:\n");
				Display_Sq(L);									//调用函数
				break;
			//插入学生信息到指定位置
			case 3:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无可供插入的位置!\n");
					break;
				}
				printf("\t\t>>>请输入插入位置:");
				scanf("%d",&n);
				Insert_Sq(L,n);
				Display_Sq(L);
				break;
		    //删除指定位置的学生记录
			case 4:
				if(L.length==1){
					printf("\t\t学生表为空,无可供删除的学生信息!\n");
					break;
				}
				printf("\t\t>>>请输入删除位置:\n");
				scanf("%d",&n);
				Delete_Sq(L,n);
				Display_Sq(L);
				break;
			//统计表中学生人数
			case 5:
				if(L.length==1)
				{
					printf("\t\t现表中的学生总数为 0 人\n");
					break;
				}
				printf("\t\t现表中的学生总数为:");
				GetLen_Sq(L);
				break;
            //利用直接插入排序按姓名进行排序
			case 6:
				if(L.length==1)
				{
				    printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				InsertSort(L);
				printf("\t\t按姓名进行直接插入法排序的结果为:\n");
				Display_Sq(L);
				break;
            //利用折半插入排序按姓名进行排序
            case 7:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				BInsertSort(L);
				printf("\t\t按姓名折半插入排序的结果为:\n");
				Display_Sq(L);
				break;
			//利用快速排序按学号进行排序
			case 8:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				QSort(L,1,L.length-1);
				printf("\t\t按学号进行快速排序的结果为:\n");
				Display_Sq(L);
				break;
			//根据姓名进行折半查找,成功返回此学生的学号和成绩
			case 9:
				if(L.length==1)
				{

					printf("\t\t学生表为空,无可供查找的学生信息!\n");
					break;
				}
				InsertSort(L);	//先进行姓名的直接插入排序
				printf("\t\t>>>请输入查找学生的姓名:");
				scanf("%s",names);
				int n1,low,high;
				low=1;
				high=L.length-1;
				n1=Search_Bin(L,names,low,high);	//调用折半查找
				if(n1==-1){
					printf("\t\t未找到该姓名的学生!\n");
					break;
				}
				printf("\t\t学号:%s\n",L.elem[n1].no);
				printf("\t\t成绩:%f\n",L.elem[n1].score);
				break;
			//根据学号进行折半查找,成功返回此学生的姓名和成绩
			case 10:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无可供查找的学生信息!\n");
					break;
				}
				QSort(L,1,L.length-1);		//先进行学号的快速排序 
				printf("t\t>>>请输入查找学生的学号:\n");
				scanf("%s",nos);
				int n2;
				n2=Search_Bin1(L,nos);		//调用折半查找
				if(n2==-1)
				{
					printf("\t\t未找到该学号的学生!\n");
					break;
				}
				printf("\t\t姓名:%s\n",L.elem[n2].name);
				printf("\t\t成绩:%f\n",L.elem[n2].score);
				break;
		    //退出系统
			case 11:
				return 0}
	
		printf("\n");
	}	
}

3.14、主要功能算法的时间复杂度

Cout函数的时间复杂度为:O(n2)

CreatHuffmanTree函数的时间复杂度为:O(n)

CreatHuffmanCode函数的时间复杂度为:O(n)

Code函数的时间复杂度为:O(n)

4、测试分析

4.1、解决问题方法以及对设计与实现的回顾讨论和分析:

在进入某个功能模块时,或者某个功能的某个步骤时,可以允许出现输入错误。因此,要实现进入某个步骤时实现撤销操作。

4.2、经验和体会

由于第一次写这么复杂的程序,开始有点无从下手,在选择合适的数据结构的时候不知道怎么去选,只能一个一个的去试,最后从结合了C语言的结构体和程序需要用到的算法中慢慢摸索到了合适的数据结构,写程序时会出现好多小的语法问题或者逻辑问题,一点点逻辑问题就会让人抓狂。但最后还是静下心来梳理情绪,慢慢的找到了问题。开始的时候没有好好理解折半插入排序。便把第0个位置也存了信息。导致哨兵没地方放。然后又全部修改了。也许哨兵不一定要放在第0个位置。但开始遇到的这个问题时,脑子里就只有一个想法,就是全部把信息修改一遍,虽然这看起来不是一个好办法,但易于修改。

4.3、算法的时空分析

T(n)=O(n2)

4.4、测试和功能展示

4.4.1、学生管理系统的建立

4.4.2、显示学生信息

4.4.3、插入学生信息

学生管理系统的设计与实现(c语言版本数据结构)_第4张图片

4.4.4、删除学生信息

学生管理系统的设计与实现(c语言版本数据结构)_第5张图片

4.4.5、统计表中学生人数

在这里插入图片描述

4.4.6、利用直接插入排序按姓名进行排序

4.4.7、利用折半插入排序按姓名进行排序

4.4.8、利用快速排序按学号进行排序

4.4.9、根据姓名进行折半查找,成功返回此学生的学号和成绩

4.4.10、根据学号进行折半查找,成功返回此学生的姓名和成绩

5、源程序清单(源程序清单是带详细注释的源程序)

#include   //头文件
#include 
#define ERROR 0     //用于返回错误
#define OK 1        //用于返回正确
#define SIZE 100    //定义stduent的大小
typedef int Status;   
//student 的结构体
typedef struct
{
    char no[8];   //学号
    char name[20]; //姓名
    float score;     //成绩
}Student;
//SqList表的结构体
typedef struct
{
    Student *elem;	//定义指向Student的指针
    int length;//当前长度
    int listsize;
}SqList;

//输入学生信息
Status InitList_Sq(SqList &L,int n)
{
	int i;
    L.elem=new Student[SIZE];
	L.length=1;		       //留下L.elem[0]作为哨兵
    //输入学生信息
	printf("\t\t请按顺序输入学生学号,姓名,成绩,不同项之间用Tab隔开:\n");
    printf("\t\t学号	姓名    成绩	\n");
    for(i=1;i<=n;i++)  	//输入学生信息
    {
		L.length++;     //表的长度加一
        printf("\t\t");
        scanf("%s %s %f", L.elem[i].no, L.elem[i].name,&L.elem[i].score);
		printf("\n");
    }
    printf("\t\t提示:成绩存入完毕!\n\n");
    printf("\t\t\t------请继续--------\n");
	return OK;
}
//打印学生信息
Status Display_Sq(SqList L)
{	
	printf("\t\t位置\t学号\t姓名\t成绩\n");
	for(int j= 1; j<L.length; j++)
    {
        printf("\t\t%d\t%s\t%s\t %.2f\t\t\n\n",j, L.elem[j].no, L.elem[j].name, L.elem[j].score);
	}
	return OK;
}
//插入学生信息到表
Status Insert_Sq(SqList &L,int n)
{	
	if(L.length==SIZE)			//考虑表中空间已满的情况
	{
		printf("\t\t操作失败,系统空间已满\n");
		return ERROR;
	}
	if(n<1||n>L.length)
	{			
		printf("\t\t操作失败,您要插入的位置不存在!\n");
		return ERROR;
	}
	for(int i=L.length-1;i>=n;i--)
		L.elem[i+1]=L.elem[i];		//依次将各学生的信息赋给其下一个位置
	printf("\t\t>>>输入要插入的学生信息:\n");
	printf("\t\t>>>学号:");
	scanf("%s",L.elem[n].no);
	printf("\n");
	printf("\t\t>>>姓名");
	scanf("%s",L.elem[n].name);
	printf("\n");
	printf("\t\t>>>成绩:");
	scanf("%f",&L.elem[n].score);
	printf("\n");
	L.length++;			//表长增加1
	printf("\t\t插入学生信息成功!\n");
	return OK;
}
//删除学生信息
Status Delete_Sq(SqList &L,int n)
{
	if(n<1||n>L.length){
		printf("\t\t操作失败,您要删除的位置不存在!\n");
		return ERROR;
	}
	for(int i=n;i<=L.length-1;i++)
		L.elem[i]=L.elem[i+1];			//依次将各学生的信息赋给其上一个位置
	L.length--;							//表长减少1
	printf("\t\t删除学生信息成功!\n");
	return OK;
}
//统计学生总数
Status GetLen_Sq(SqList &L)
{
 
	printf("\t\t-----学生个数=-----\n");
    printf("%d",L.length-1);
	return OK;
}
//按姓名直接插入排序
void InsertSort(SqList &L)
{
	int i,j;
    for(i=2;i<L.length;++i)
     if(strcmp(L.elem[i].name,L.elem[i-1].name)==-1)
       {
		 L.elem[0]=L.elem[i]; // 复制为哨兵
         L.elem[i]=L.elem[i-1];
         for(j=i-2;strcmp(L.elem[0].name,L.elem[j].name)==-1;--j)
	            L.elem[j+1]=L.elem[j]; // 记录后移 
         L.elem[j+1]=L.elem[0]; //插入到正确位置
       }
 }

//按姓名折半插入排序
//按姓名折半插入排序
//设这两个字符串为str1,str2,

//若str1==str2,则返回零;

//若str1

//若str1>str2,则返回正数。

//matlab中函数,strcmp(s1,s2) 判断两个字符串s1和s2是否相同,相同返回true ,不同返回false

//当s1

//当s1==s2时,返回值= 0;

//当s1>s2时,返回正数。

//即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:

Status BInsertSort (SqList &L)
{ 
	int low,high,m;		
	for(int i=2;i<L.length;++i){  
		L.elem[0]=L.elem[i];	// 复制为哨兵
		low=1;
		high=i-1;
		while(low<=high){	//利用折半方法找到插入位置	
			m=(low+high)/2; 
            if(strcmp(L.elem[0].name,L.elem[m].name)<0)
				high=m-1;
            else
				low=m+1; 
           }
		for(int j=i-1;j>=high+1;--j)	//纪录后移
			L.elem[j+1]=L.elem[j];
			L.elem[high+1]=L.elem[0];
    }
	return OK;
}
//按学号快速排序
int pivotloc;
char pivotkey[10];
int Partition(SqList &L,int low,int high)
{
	L.elem[0]=L.elem[low];
	strcpy(pivotkey,L.elem[low].no);
	while(low<high)
	{
		while(low<high&&strcmp(L.elem[high].no,pivotkey)>=0)
	   //若有比哨兵小的high,则将其赋给low,否则high前移
			--high;
		L.elem[low]=L.elem[high];
		while(low<high&&strcmp(L.elem[low].no,pivotkey)<=0)	
		//若有比哨兵大的low,则将其赋给high,否则low后移
			++low;
		L.elem[high]=L.elem[low];
	}
    L.elem[low]=L.elem[0]; 
    return low;
}
void QSort(SqList &L,int low,int high)
{
	if(low<high)
	{
		pivotloc=Partition(L,low,high);		
        QSort(L,low,pivotloc-1);	//递归调用对左子表排序
        QSort(L,pivotloc+1,high);	//递归调用对右子表排序
    }
}
//按姓名折半查找(递归)
int Search_Bin(SqList &L,char *s,int low,int high)
{
	int m;
	if(low<=high)
	{
		m=(low+high)/2;
		if(strcmp(s,L.elem[m].name)==0)
			return m;
		else if(strcmp(s,L.elem[m].name)<0)
			return Search_Bin(L,s,low,m-1);		//对左子表折半查找
		else
			return Search_Bin(L,s,m+1,high);	//对右子表折半查找
	}
	return -1;
}
//按学号进行折半查找(非递归)
int Search_Bin1(SqList &L,char *s)
{
	int m,low=1,high=L.length-1;
	while(low<=high)
	{
		m=(low+high)/2;
		if(strcmp(s,L.elem[m].no)==0)
			return m;
		else if(strcmp(s,L.elem[m].no)<0)
			high=m-1;
		else
			low=m+1;
	}
	return -1;
}
//菜单选项
void memu(void)
{
	printf("\t\t||************ 欢迎使用学生信息管理系统!****************||\n");
	printf("\t\t||**name:伍思源 number:182034490136    电信18-1   *******||\n");
	printf("\t\t||   *********************************                   ||\n");
    printf("\t\t||   *           功能菜单          *                     ||\n");
    printf("\t\t||   *********************************                   ||\n");
	printf("\t\t||   1.输入学生信息                                      ||\n");
	printf("\t\t||   2.逐个显示学生的相关信息                            ||\n");
	printf("\t\t||   3.插入学生信息到指定位置                            ||\n");
	printf("\t\t||   4.删除指定位置的学生记录                            ||\n");
    printf("\t\t||   5.统计表中学生人数                                  ||\n");
	printf("\t\t||   6.利用直接插入排序按姓名进行排序                    ||\n");
	printf("\t\t||   7.利用折半插入排序按姓名进行排序                    ||\n");
	printf("\t\t||   8.利用快速排序按学号进行排序                        ||\n");
	printf("\t\t||   9.根据姓名进行折半查找,成功返回此学生的学号和成绩  ||\n");
	printf("\t\t||  10.根据学号进行折半查找,成功返回此学生的姓名和成绩  ||\n");
	printf("\t\t||  11.退出系统\n");
	printf("\t\t>>>请选择您需要的服务(1--11):");
}
int main(void)
{
	int no;
	int n;
	char names[20],nos[10];
	SqList L;
	L.length=1;
	while(1)
	{
		memu();
		scanf("%d",&no);
		printf("\n");
		switch(no)
		{

            //输入学生信息
			case 1:  
				printf("\t\t>>>请输入学生个数:");
				scanf("%d",&n);
				InitList_Sq(L,n);
				break;
            //逐个显示学生的相关信息
			case 2:
				if(L.length==1)
				{								//判断表是否为空
					printf("\t\t学生表为空,无可显示的学生信息!\n");
					break;
				}
				printf("\t\t>>>输出学生信息:\n");
				Display_Sq(L);									//调用函数
				break;
			//插入学生信息到指定位置
			case 3:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无可供插入的位置!\n");
					break;
				}
				printf("\t\t>>>请输入插入位置:");
				scanf("%d",&n);
				Insert_Sq(L,n);
				Display_Sq(L);
				break;
		    //删除指定位置的学生记录
			case 4:
				if(L.length==1){
					printf("\t\t学生表为空,无可供删除的学生信息!\n");
					break;
				}
				printf("\t\t>>>请输入删除位置:\n");
				scanf("%d",&n);
				Delete_Sq(L,n);
				Display_Sq(L);
				break;
			//统计表中学生人数
			case 5:
				if(L.length==1)
				{
					printf("\t\t现表中的学生总数为 0 人\n");
					break;
				}
				printf("\t\t现表中的学生总数为:");
				GetLen_Sq(L);
				break;
            //利用直接插入排序按姓名进行排序
			case 6:
				if(L.length==1)
				{
				    printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				InsertSort(L);
				printf("\t\t按姓名进行直接插入法排序的结果为:\n");
				Display_Sq(L);
				break;
            //利用折半插入排序按姓名进行排序
            case 7:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				BInsertSort(L);
				printf("\t\t按姓名折半插入排序的结果为:\n");
				Display_Sq(L);
				break;
			//利用快速排序按学号进行排序
			case 8:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无排序结果!\n");
					break;
				}
				QSort(L,1,L.length-1);
				printf("\t\t按学号进行快速排序的结果为:\n");
				Display_Sq(L);
				break;
			//根据姓名进行折半查找,成功返回此学生的学号和成绩
			case 9:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无可供查找的学生信息!\n");
					break;
				}
				InsertSort(L);	//先进行姓名的直接插入排序
				printf("\t\t>>>请输入查找学生的姓名:");
				scanf("%s",names);
				int n1,low,high;
				low=1;
				high=L.length-1;
				n1=Search_Bin(L,names,low,high);	//调用折半查找
				if(n1==-1){
					printf("\t\t未找到该姓名的学生!\n");
					break;
				}
				printf("\t\t学号:%s\n",L.elem[n1].no);
				printf("\t\t成绩:%f\n",L.elem[n1].score);
				break;
			//根据学号进行折半查找,成功返回此学生的姓名和成绩
			case 10:
				if(L.length==1)
				{
					printf("\t\t学生表为空,无可供查找的学生信息!\n");
					break;
				}
				QSort(L,1,L.length-1);		//先进行学号的快速排序 
				printf("t\t>>>请输入查找学生的学号:\n");
				scanf("%s",nos);
				int n2;
				n2=Search_Bin1(L,nos);		//调用折半查找
				if(n2==-1)
				{
					printf("\t\t未找到该学号的学生!\n");
					break;
				}
				printf("\t\t姓名:%s\n",L.elem[n2].name);
				printf("\t\t成绩:%f\n",L.elem[n2].score);
				break;
		    //退出系统
			case 11:
				return 0;
		}
		printf("\n");
	}	
}

6、用户使用手册

用户执行代码后,主菜单会显示10个功能,分别为:

  1. 根据指定学生个数,逐个输入学生信息;

(2) 逐个显示学生表中所有学生的相关信息;

(3) 给定一个学生信息,插入到表中指定的位置;

(4) 删除指定位置的学生记录;

(5) 统计表中学生个数;

(6) 利用直接插入排序或者折半插入排序按照姓名进行排序;

(7) 利用快速排序按照学号进行排序;

(8) 根据姓名进行折半查找,要求使用递归算法实现,成功返回此学生的学号和成绩;

(9) 根据学号进行折半查找,要求使用非递归算法实现,成功返回此学生的姓名和成绩。

首先,用户根据提示选择功能(1): 输入学生信息。再根据提示分别输入学生的学号、姓名、成绩。

接着,用户可以根据自己的需求选择功能。若选择功能(2): 显示学生相关信息,则会显示学生相关信息。

若选择功能(3):插入学生到指定的位置,则根据提示输入插入学生的学号、姓名和成绩。

若选择功能(4): 删除指定位置的学生记录,则根据提示删除用户需要删除的记录。

若选择功能(5): 统计表中学生个数,则会显示出学生的个数。

若选择功能(6):按姓名进行折半插入排序,则根据提示输入学生姓名,则可以显示折半插入后的顺序。

若选择功能(7):按照学号进行快速排序,则输入学生的学号,则可显示快速排序后的顺序。

若选择功能(8):根据姓名进行折半查找,要求使用递归算法实现,则根据提示输入学生的姓名,就可以显示出结果。

若选择功能(9):根据学号进行折半查找,用非递归算法实现,则根据提示输入学生的学号,就可以显示出结果。

你可能感兴趣的:(数据结构的课堂设计,数据结构,c语言,案例,项目开发)