一、实验目的
1.理解排序和查找的概念和意义;
2. 掌握顺序查找、折半查找、直接插入排序,改进的冒泡排序、快速排序等算法。
二、实验内容
有n(n至少为100)个学生记录,每个学生记录包含姓名、性别、班号(班号为1001—1030之间)。现编写程序实现以下功能:
(1)利用文件输入学生记录;
(2)分别按班号或姓名采用顺序查找或折半查找算法实现查找指定学生记录并输出,若未找到则输出“查无此人”信息;
(3)按班号和性别有序输出,即先按班号输出,同一个班的学生按性别输出。
三、实验要求
1. 程序要添加适当的注释,程序的书写要采用缩进格式。
2. 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。
3. 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
4. 实验课前完成实验内容源程序的初稿;实验课对源程序进行编辑、调试、运行;实验课后按规定时间上交实验内容。
5. 按照实验内容完成程序编写,并按要求提交下面内容,写清班级和姓名。
1)给出该实验内容实现的分析研究过程的描述:
(1)数据结构和存储结构选取的理由和类型定义;
(2)分别用顺序查找和折半查找算法对实现查找功能部分进行分析研究,并给出效率对比,从而给出实现实验内容2的选择理由。
(3)分别用直接插入排序、快速排序、改进冒泡排序、简单选择算法
对实现排序功能部分进行分析研究,并给出效率对比,从而给出实现实验内容3的选择理由。
2)源代码和运行结果截图粘贴到word文档中,A4正反打印。
以上一起装订提交。
代码解析:
这次的实验很简单,和以前完成的实验一即学生信息库差不多
注:排序的算法可以自行比较,并且可以运用time.h头文件令a=clock_h();b=clock_h();计算程序排序的运行时间,进行比较
头文件与学生顺序表的定义:
#include<iostream>
#include<fstream>
#include <stdlib.h>
#include<algorithm>
#include<time.h>
#include<string.h>
#define maxsize 20000
using namespace std;
typedef struct {
string name;
string xb;
int classes;
}Students;
typedef struct {
Students* elem;
int length;
}SqList;
/*顺序表的定义*/
创建学生信息库并使用文件输入学生信息:
/*创建学生表并使用文件输入部分代码*/
void InitList(SqList& L) {
void count(SqList & L);
int i = 0;
L.length = 0;
fstream file;//文件输入
file.open("学生信息库.txt");
if (!file) cout << "|------未找到学生信息库.txt文件------|" << endl;
else {
L.elem = new Students[maxsize];
if (!L.elem)
cout << "|---------创建学生信息库失败---------|" << endl;
else {
while (!file.eof()) {
file >> L.elem[i].classes >> L.elem[i].name >> L.elem[i].xb;
L.length = ++i;
}
cout << "|-----输入学生信息库.txt信息完毕-----|" << endl;
cout << "|---------创建学生信息库成功---------|" << endl;
}
}
file.close();
count(L);
}
/*创建学生表并使用文件输入部分代码*/
统计学生数量不为零的班级学生个数并输出 :
/*计算各班数量不为0的人数并存储到数组中部分代码*/
int num[31];//各班人数数组
void count(SqList& L) {
int i;
for (i = 0; i <= 30; ++i)
num[i] = 0;
for (i = 0; i < L.length; ++i)
num[L.elem[i].classes - 1000] += 1;
}
/*计算各班数量不为0的人数并存储到数组中部分代码*/
/*输出各班人数*/
void outcount() {
for (int i = 1; i <= 30; ++i) {
if (num[i])
cout << 1000 + i << "班有" << num[i] << "人" << "\t";
if (i % 5 == 0)
cout << endl;
}
}
/*输出各班人数*/
/*按班级排序并以文件存储部分代码*/
将学生信息按班级排序并输出为文件:
(注释使用的是最基础的冒泡排序,另一种为改进的冒泡排序,即设置一个bool类型的标记变量flag)
/*按班级排序并以文件存储部分代码*/
int sortclasses(SqList& L) {
ofstream outfile("班号排序学生信息库.txt");
int i, j;
Students temp;
E:/* for (i = 0; i < L.length - 1; ++i) {
for (j = i + 1; j < L.length; ++j) {
if (L.elem[j].classes < L.elem[i].classes) {
temp = L.elem[i];
L.elem[i] = L.elem[j];
L.elem[j] = temp;
}
}
}*/
int len = L.length;
bool flag = true;
while (flag) {
flag = false;
for (int i = 1; i < len; i++) {
if (L.elem[i-1].classes > L.elem[i].classes) {
temp = L.elem[i];
L.elem[i] = L.elem[i - 1];
L.elem[i - 1] = temp;
flag = true;
}
}
len--;
}
for (i = 0; i < L.length; ++i)
outfile << L.elem[i].classes << "\t" << L.elem[i].name << "\t" << L.elem[i].xb << endl;
for (i = 1; i <= 30; ++i)
if (num[i]) {
outfile << 1000 + i << "班有" << num[i] << "人" << endl;
num[0] += 1;
}
outfile.close();
return 1;
}
/*按班级排序并以文件存储部分代码*/
按班级班号查找学生信息:
班号相同的信息则按照男女生顺序进行排序
(班号有序情况,顺序查找)
/*(班号有序情况)*/
void findsortclasses(SqList& L) {
void sortxb(SqList & L);
A: int low = 0, high = L.length - 1, mid = (low + high) / 2, flag = 0, n, i;
string a;
cout << "<<<请输入所需查找的班号:" ;
cin >> n;
while (low <= high) {
if (L.elem[mid].classes == n) break;
else if (L.elem[mid].classes > n) {
high = mid - 1;
mid = (high + low) / 2;
}
else {
low = mid + 1;
mid = (high + low) / 2;
}
}
if (low > high) {
cout << "未找到班号为" << n << "的学生信息!" << endl;
cout << "是否继续按班号查找:(yes or no)" << endl;
cin >> a;
if (a == "yes") goto A;
else if (a == "no") return;
else cout << "输入错误!" << endl;
}
else {
sortxb(L);
cout << "|--班级" << "\t" << "姓名" << "\t" << "性别--|" << endl;
while (1) {
if (L.elem[mid++].classes != n)
break;
}
for (i = mid - num[n - 1000]; i < mid; i++)
cout << " " << L.elem[i - 1].classes << "\t" << L.elem[i - 1].name << "\t" << L.elem[i - 1].xb << endl;
}
}
(班级无序情况,折半查找)
/*(班号无序情况)*/
void findclasses(SqList& L) {
int n, i, j = 0,k=0,l=0;
string a;
Students temp[100],b;
B: cout << "<<<请输入所需查找的班号:" ;
cin >> n;
for (i = 0; i < L.length; ++i)
if (L.elem[i].classes == n)
temp[j++] = L.elem[i];
if (j == 0) {
cout << "未找到班号为:" << n << " 的同学!" << endl;
cout << "是否继续按班号查找:(yes or no)" << endl;
cin >> a;
if (a == "yes") goto B;
else if (a == "no") return;
else cout << "输入错误!" << endl;
}
else {
for (i = 0; i < j; ++i) {
if (temp[i].xb == "男") {
b = temp[i];
temp[i] = temp[l];
temp[l++] = b;
}
}
cout << "班号为: " << n << " 的同学共有" << j << "名" << endl << "信息如下:" << endl;
cout << "|--班级" << "\t" << "姓名" << "\t" << "性别--|" << endl;
for (i = 0; i < j; i++)
cout << " " << temp[i].classes << "\t" << temp[i].name << "\t" << temp[i].xb << endl;
}
}
/*按班号查找并输出学生信息部分代码*/
将学生信息按姓名排序并输出为文件:
(使用的是冒泡排序算法)
/*按姓名排序并以文件存储部分代码*/
void sortname(SqList& L) {
ofstream outfile("姓名排序学生信息库.txt");
int i, j;
Students temp;
for (i = 0; i < L.length - 1; ++i) {
for (j = i + 1; j < L.length; ++j) {
if (L.elem[j].name < L.elem[i].name) {
temp = L.elem[i];
L.elem[i] = L.elem[j];
L.elem[j] = temp;
}
}
}
for (i = 0; i < L.length; ++i)
outfile << L.elem[i].classes << "\t" << L.elem[i].name << "\t" << L.elem[i].xb << endl;
for (i = 01; i <= 30; ++i)
if (num[i])
outfile << 1000 + i << "班有" << num[i] << "人" << endl;
outfile.close();
cout << "已将学生信息按班号排序并输出为文件" << endl;
}
/*按姓名排序并以文件存储部分代码*/
按姓名查找输出学生信息:
(姓名有序,按字母排序,顺序查找,注意重名情况)
/*姓名有序情况*/
void findsortname(SqList& L) {
int find1(SqList & L, int mid, string name);
int find2(SqList & L, int mid, string name);
void sortnameclass(SqList L, int min, int max);
D: int low = 0, high = L.length - 1, mid = (low + high) / 2, flag = 0, min, max;
string a, n;
cout << "<<<请输入所需查找的姓名:";
cin >> n;
while (low <= high) {
if (L.elem[mid].name == n) break;
else if (L.elem[mid].name > n) {
high = mid - 1;
mid = (high + low) / 2;
}
else {
low = mid + 1;
mid = (high + low) / 2;
}
}
if (low > high) {
cout << "未找到姓名为" << n << "的学生信息!" << endl;
cout << "是否继续按姓名查找:(yes or no)" << endl;
cin >> a;
if (a == "yes") goto D;
else if (a == "no") return;
else cout << "输入错误!" << endl;
}
else {
cout << "|--班级" << "\t" << "姓名" << "\t" << "性别--|" << endl;
if (mid == 0) {
max = find2(L, mid, n);
sortnameclass(L, mid, max);
for (; mid < max; ++mid)
cout << " " << L.elem[mid].classes << "\t" << L.elem[mid].name << "\t" << L.elem[mid].xb << endl;
}
else if (mid == L.length - 1) {
min = find1(L, mid, n);
sortnameclass(L, min, mid);
for (; min < mid; ++min)
cout << " " << L.elem[mid].classes << "\t" << L.elem[mid].name << "\t" << L.elem[mid].xb << endl;
}
else {
min = find1(L, mid, n);
max = find2(L, mid, n);
min += 1;
sortnameclass(L, min, max);
while (min < max) {
cout << " " << L.elem[min].classes << "\t" << L.elem[min].name << "\t" << L.elem[min].xb << endl;
min += 1;
}
}
}
}
用于找重名情况:
/*拥有相同名字的最开始位置*/
int find1(SqList& L, int mid, string name) {
while (L.elem[mid].name == name) {
mid -= 1;
}
return mid;
}
/*拥有相同名字的最末尾位置*/
int find2(SqList& L, int mid, string name) {
while (L.elem[mid].name == name) {
mid += 1;
}
return mid;
}
/*姓名有序情况*/
姓名无序的情况:
顺序查找,重名的按照班级排序
/*姓名无序情况*/
void findname(SqList& L) {
string name, a;
Students temp[10],b;
int i, j = 0,k;
C: cout << "<<<请输入所需查找的姓名:" ;
cin >> name;
for (i = 0; i < L.length; ++i)
if (L.elem[i].name == name)
temp[j++] = L.elem[i];
if (j == 0) {
cout << "未找到姓名为:" << name << " 的同学!" << endl;
cout << "是否继续按姓名查找:(yes or no)" << endl;
cin >> a;
if (a == "yes") goto C;
else if (a == "no") return;
else cout << "输入错误!" << endl;
}
else {
for (i = 0; i < j; i++)
for(k=i+1;k<j;k++)
if (temp[i].classes > temp[k].classes) {
b = temp[k];
temp[k] = temp[i];
temp[i] = b;
}
cout << "姓名为: " << name << " 的同学共有" << j << "名" << endl << "信息如下:" << endl;
cout << "|--班级" << "\t" << "姓名" << "\t" << "性别--|" << endl;
for (i = 0; i < j; i++)
cout << " " << temp[i].classes << "\t" << temp[i].name << "\t" << temp[i].xb << endl;
}
}
/*姓名无序情况*/
/*按姓名查找并输出学生信息部分代码*/
/*在重名情况下对名字的班级进行排序*/
/*在重名情况下对名字的班级进行排序*/
void sortnameclass(SqList L, int min, int max) {
int i;
Students temp;
bool flag = true;
for (; min < max; ++min) {
for (i = min + 1; i < max; ++i) {
if (L.elem[i].classes < L.elem[min].classes) {
temp = L.elem[i];
L.elem[i] = L.elem[min];
L.elem[min] = temp;
}
}
}
}
/*在重名情况下对名字的班级进行排序*/
/*在相同的班级内整理性别顺序*/
/*在班级内整理性别顺序*/
void sortxb(SqList& L) {
Students temp;
int i, j = 0, k, l;
for (i = 1; i <= 30; ++i) {
if (num[i]) {
l = j;
for (k = j; k < j + num[i]; ++k)
if (L.elem[k].xb == "男") {
temp = L.elem[k];
L.elem[k] = L.elem[l];
L.elem[l] = temp;
l += 1;
}
j = k;
}
}
}
/*在班级内整理性别顺序*/
/*将按照班级与性别排序的学生库输出为文件*/
/*将按照班级与性别排序的学生库输出为文件*/
void printf4(SqList& L) {
ofstream outfile("班级性别排序学生信息库.txt");
for (int i = 0; i < L.length; ++i)
outfile << L.elem[i].classes << "\t" << L.elem[i].name << "\t" << L.elem[i].xb << endl;
for (int i = 1; i <= 30; ++i)
if (num[i])
outfile << 1000 + i << "班有" << num[i] << "人" << endl;
outfile.close();
cout << "|-已将学生信息按班号性别排序并输出为文件-|" << endl;
}
/*将按照班级与性别排序的学生库输出为文件*/
输出全部学生信息:
/*输出全部学生信息*/
void output(SqList& L) {
cout << "|--班级" << "\t" << "姓名" << "\t" << "性别--|" << endl;
for (int i = 0; i < L.length; ++i)
cout << " " << L.elem[i].classes << "\t" << L.elem[i].name << "\t" << L.elem[i].xb << endl;
outcount();
cout << "学生信息库中共储存有" << L.length << "名学生信息" << endl;
}
/*输出全部学生信息*/
菜单函数:
void mune1() {
cout << "<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << endl;
cout << "|------查找和排序算法的综合应用------|" << endl;
cout << "|-------------请输入操作:-----------|" << endl;
cout << "|-----------1.输入学生信息-----------|" << endl;
cout << "|-----------2.统计各班人数-----------|" << endl;
cout << "|-----------3.查找学生记录-----------|" << endl;
cout << "|-------4.按班号和性别有序输出-------|" << endl;
cout << "|---------------0.退出---------------|" << endl;
cout << "<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << endl;
}
主函数部分:
int main() {
SqList L;
clock_t start, end;
int n = 0, flag = 0, x, a = 0, b = 0, choose;
mune1();
do {
cout << "<<<请选择操作: ";
cin >> n;
switch (n) {
case 1:
InitList(L);
break;
case 2:
/*start = clock();*/
outcount();
/*end = clock();*/
/*cout << "输出人数所需时间为" << (end - start) * 1000 / CLOCKS_PER_SEC << endl;*/
break;
case 3:
cout << "|-----------请选择查找方式:----------|" << endl;
cout << "|--------1.按班号查找学生记录--------|" << endl;
cout << "|--------2.按姓名查找学生记录--------|" << endl;
cout << "|---------------0.退出---------------|" << endl;
cout << "<<<请选择操作: ";
cin >> choose;
if (choose == 1) {
cout << "|--------将按班号查找学生记录--------|" << endl;
if (!a || b) {
cout << "<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << endl;
cout << "是否将学生信息按班号排序并输出为文件:" << endl;
cout << "\t" << "1.是" << "\t" << "2.否" << endl;
cin >> x;
}
if (x == 1) {
/*start = clock();*/
if (sortclasses(L)) cout << "|-已将学生信息按班号排序并输出为文件-|" << endl;
/*end = clock();*/
/*cout << "班号排序所需时间为" << (end - start) * 1000 / CLOCKS_PER_SEC << endl;*/
/*start = clock();*/
findsortclasses(L);//折半查找
/*end = clock();*/
/*cout << "折半查找所需时间为" << (end - start) * 1000 / CLOCKS_PER_SEC << endl;*/
flag = 1;
a = 1;
b = 0;
}
else if (x == 2)
findclasses(L);//顺序查找
}
else if (choose == 2) {
cout << "|--------将按姓名查找学生记录--------|" << endl;;
if (a || !b) {
cout << "<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>" << endl;
cout << "是否将学生信息按姓名排序并输出为文件:" << endl;
cout << "\t" << "1.是" << "\t" << "2.否" << endl;
cin >> x;
}
if (x == 1) {
sortname(L);
findsortname(L);
b = 1;
a = 0;
flag = 0;
}
else if (x == 2) {
findname(L);
}
}
else break;
break;
case 4:
cout << "|-将按照班号大小以及男女性别顺序输出-|" << endl;
if (!a) sortclasses(L);
sortxb(L);
output(L);
printf4(L);
break;
}
} while (n != 0);
cout << "<<<<<<<<<<<<<感谢您的使用>>>>>>>>>>>>>" << endl;
system("pause");
}
运行的结果