数据结构与算法(C语言实现) 7-8.查找和排序算法的综合应用

该实验旨在理解和掌握排序(直接插入排序、冒泡排序改进、快速排序)和查找(顺序查找、折半查找)算法。程序读取包含姓名、性别、班号的学生记录,实现按班号或姓名查找,并按班号和性别排序输出。实验中使用了多种排序和查找策略,对比了它们的效率,并记录了操作时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验七-八  查找和排序算法的综合应用

一、实验目的

1.理解排序和查找的概念和意义;

2. 掌握顺序查找、折半查找、直接插入排序,改进的冒泡排序、快速排序等算法。

二、实验内容

有n(n至少为100)个学生记录,每个学生记录包含姓名、性别、班号(班号为1001—1030之间)。现编写程序实现以下功能:

(1)利用文件输入学生记录;

(2)分别按班号或姓名采用顺序查找折半查找算法实现查找指定学生记录并输出,若未找到则输出“查无此人”信息;

(3)按班号和性别有序输出,即先按班号输出,同一个班的学生按性别输出。


头文件及宏定义:

/*CaptainUniverse_ 2022.6.9*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define SQ 1
#define BI 2
#define TRUE 1
#define FALSE 0
#define by_name 1
#define by_class 2

typedef int Status;
typedef struct Student
{
    char name[10];
    char sex[5];
    char class[15];
}Student;
typedef struct
{
    Student *data;
    int length;
}*StudentList;

Status getFileFlag=FALSE;
/*CaptainUniverse_ 2022.6.9*/

子函数声明:

/*CaptainUniverse_ 2022.6.9*/
Status getFileList(StudentList,long);//文件读取信息表
void display(StudentList,int*,char*);//输出查找内容
void Bi_name_display(StudentList,int*,int,char*);
void Quicktsort(StudentList,int,int);//快速排序
void Insertsort(StudentList);//直接插入排序
void Selectsort(StudentList);//选择排序
void BubbleSort_plus(StudentList);//冒泡排序改进
void Sexsort(StudentList);//选择排序(性别)
void Namesort(StudentList);//选择排序(姓名) 
int *Sq_Search(StudentList,char*,Status,Status);//顺序查找 返回序号数组
int *Binary_Search(StudentList,char*,Status,Status);//二分查找 返回序号数组
int *FindMore(StudentList,char*,Status,Status,int);
void Sort(StudentList,int,int);
/*CaptainUniverse_ 2022.6.9*/

子函数主体:

/*CaptainUniverse_ 2022.6.9*/
void Sort(StudentList L,int choice,int length)
{
	if(choice==1)
		Insertsort(L);
	else if(choice==2)
		Selectsort(L);
	else if(choice==3)
		Quicktsort(L,1,length);
	else
		BubbleSort_plus(L);	
}

void Bi_name_display(StudentList L,int *save,int choice,char *key)
{
	if(save[0]!=FALSE)
	{
		StudentList temp=(StudentList) malloc(sizeof (StudentList));
		temp->length=save[1]-save[0]+1;
		temp->data=(Student *) malloc((temp->length)*sizeof (Student));
		
		int i,j;
		for(i=1,j=save[0];j<=save[1];i++,j++)
			temp->data[i]=L->data[j];
		
		Sort(temp,choice,temp->length);
		int temp_save[2]={1,temp->length};
		display(temp,temp_save,key);		
	}
	else
		printf("查无此人!\n");
}

int *FindMore(StudentList L,char* key,Status flag,Status way,int first)
{
	int *save=(int *)malloc(2*sizeof(int));
	save[0]=save[1]=first;
	if(!first)
		return save;
	else
		if(way==SQ)
		{
			for(int i=first-1;i>0;i--)
			{
				if((flag==by_class&&!strcmp(L->data->class,key))||(flag==by_name&&!strcmp(L->data->name,key)))
					save[0]=i;
			}
		}
		else
		{
			int left,right;
			left=right=first;
			while(left-1>=1&&(flag==by_class&&(!strcmp(L->data[left].class,L->data[left-1].class)))||(flag==by_name&&(!strcmp(L->data[left].name,L->data[left-1].name))))
				left--;
			save[0]=save[1]=left;
			while(right+1<=L->length&&(flag==by_class&&(!strcmp(L->data[right].class,L->data[right+1].class)))||(flag==by_name&&(!strcmp(L->data[right].name,L->data[right+1].name))))
				right++;
			save[1]=right;	
		}
		
	return save;
}


Status getFileList(StudentList L,long MAX)
{
    FILE *fp;
    int i=1;
    if(getFileFlag==FALSE)
    {
    	getFileFlag=TRUE;
		srand(time(NULL));
		fp=fopen("学生信息输入文件.txt","w");
		char *name[60]={"赵","钱","孙","李","周","吴","郑","王","冯","陈",
			             "楮","卫","蒋","沈","韩","杨","朱","秦","尤","许",
			              "何","吕","施","张","孔","曹","严","华","金","魏",
			             "陶","姜","戚","谢","邹","喻","柏","水","窦","章",
			             "云","苏","潘","葛","奚","范","彭","郎","鲁","韦",
			             "昌","马","苗","凤","花","方","俞","任","袁","柳"}; 
		char *sex[2]={"男","女"};
		for(int i=1;i<=MAX;i++)
		{
			char fullname_temp[10],name_temp_1[3],name_temp_2[3],sex_temp[3],class_temp[5];
			int temp=1001+rand()%29;
			itoa(temp,class_temp,10);
			strcpy(fullname_temp,name[rand()%60]);
			strcpy(name_temp_1,name[rand()%60]);
			strcat(fullname_temp,name_temp_1);
			temp=rand();
			if(temp%2)
			{
				strcpy(name_temp_2,name[rand()%60]);
				strcat(fullname_temp,name_temp_2);
			}							
			strcpy(sex_temp,sex[rand()%2]);	
			fprintf(fp,"%s\t%s\t%s",class_temp,fullname_temp,sex_temp);
			if(i!=MAX)		
				fputc('\n',fp);
		}
		fclose(fp);
		printf("已将示例文件\"学生信息输入文件.txt\"放入程序目录!\n");
		printf("注意:数据间为TAB键!末行不可出现无关字符!\n");
		printf("可修改文件内容后继续操作!\n");
		system("pause");
	}
    
    if((fp=fopen("学生信息输入文件.txt","r"))==NULL)
    {
        fclose(fp);
        return FALSE;
    }
    while(!feof(fp))
    {
        fscanf(fp,"%s\t%s\t%s",L->data[i].class,L->data[i].name,L->data[i].sex);//班号 姓名 性别
        //printf("%s %s %s\n",L->data[i].class,L->data[i].name,L->data[i].sex);
        i++;
    }
    (*L).length=i-1;
 
    fclose(fp);
    return TRUE;
}

void display(StudentList L,int *save,char *key)
{
    if(save[0]!=FALSE)
    {
		for (int i = save[0]; i <= save[1]; i++)
		    if(!strcmp(L->data[i].class,key)||!strcmp(L->data[i].name,key))
		        printf("%s %s %s\n",L->data[i].class,L->data[i].name,L->data[i].sex);
		printf("\n共%d人!\n",save[1]-save[0]+1);
	}       
    if(save[0]==FALSE)
        printf("查无此人!\n");
}

void Sexsort(StudentList L)
{
    int i,j;
    for(i=1;i<=L->length;i++)
    {
        for(j=i+1;j<=L->length;j++)
        {
            if(!strcmp(L->data[i].class,L->data[j].class)&& !strcmp(L->data[i].sex,"女")&&!strcmp(L->data[j].sex,"男"))
            {
                Student student=L->data[i];
                L->data[i]=L->data[j];
                L->data[j]=student;
            }
        }
    }
}

void Namesort(StudentList L)
{
	int i,j;
	for(i=1;i<=L->length;i++)
	{
		for(j=i+1;j<=L->length;j++)
		{
			if(strcmp(L->data[i].name,L->data[j].name)>0)
			{
				Student student=L->data[i];
				L->data[i]=L->data[j];
				L->data[j]=student;
			}
		}
	} 					            		           	        
}	    

void Quicktsort(StudentList L,int first,int last)
{
    if(first>last)
        return;
    int i=first,j=last;
    Student standard=L->data[i];
    while (i!=j)
    {
        while ((strcmp(L->data[j].class,standard.class)>=0)&&i<j)
            j--;
        L->data[i]=L->data[j];
        
        while ((strcmp(L->data[i].class,standard.class)<=0)&&i<j)
            i++;
        L->data[j]=L->data[i];   
    }
    L->data[i]=standard;

    Quicktsort(L,first,i-1);
    Quicktsort(L,i+1,last);

    Sexsort(L);
}

void Insertsort(StudentList L)
{
    int i,j;
    for (i = 2; i <= L->length; i++)
    {
        if(strcmp(L->data[i-1].class,L->data[i].class)>0)
        {
            Student temp_1=L->data[i];
            for (j = i-1;strcmp(L->data[j].class,temp_1.class)>0&&j>=0; j--)
            {
                Student temp_2=L->data[j];
                L->data[j]=L->data[j+1];
                L->data[j+1]=temp_2;
            }
            L->data[j+1]=temp_1;

        }
    }
    Sexsort(L);
}

void Selectsort(StudentList L)
{
    int i,j,k;
    for(i=1;i<=L->length;i++)
    {
        k=i;
        for(j=i+1;j<=L->length;j++)
            if(strcmp(L->data[k].class,L->data[j].class)>0)
                k=j;
        if(k!=i)
        {
            Student temp=L->data[i];
            L->data[i]=L->data[k];
            L->data[k]=temp;
        }
    }
    Sexsort(L);
}

void BubbleSort_plus(StudentList L)
{
    int lastEdge=1,lastEdgetemp=1;
    for(int i=1;i<=L->length-1;i++)
    {
        lastEdge=lastEdgetemp;
        for(int j=L->length-1;j>lastEdge;j--)
        {
            if(strcmp(L->data[j-1].class,L->data[j].class)>0)
            {
                Student temp=L->data[j-1];
                L->data[j-1]=L->data[j];
                L->data[j]=temp;

                lastEdgetemp=j;
            }
        }

        if(lastEdge==lastEdgetemp)
            break;
    }
    Sexsort(L);
}

int *Sq_Search(StudentList L,char* key,Status flag,Status choice)
{
	int high=L->length;
	
	Sort(L,choice,L->length);
    
	if(flag==by_name)
	{
		strcpy(L->data[0].name,key);
		while(strcmp(L->data[high].name,key))
			high--;
	}
	else
	{
		strcpy(L->data[0].class,key);
		while(strcmp(L->data[high].class,key))
			high--;
	}
    return FindMore(L,key,flag,SQ,high);
}

int *Binary_Search(StudentList L,char* key,Status flag,Status choice)
{
	int left=1,right=L->length-1,middle;
	if(flag==by_name)
		Namesort(L);
	else
		Sort(L,choice,L->length);
	
    
    while (left<=right)
    {
    	middle=left+(right-left)/2;
    	if((flag==by_class&&strcmp(L->data[middle].class,key)>0)||(flag==by_name&&strcmp(L->data[middle].name,key)>0))
    		right=middle-1;
    	else if((flag==by_class&&strcmp(L->data[middle].class,key)<0)||(flag==by_name&&strcmp(L->data[middle].name,key)<0))
    		left=middle+1;
    	else
    		break;
    }
    return FindMore(L,key,flag,BI,middle);
}
/*CaptainUniverse_ 2022.6.9*/

主函数:

/*CaptainUniverse_ 2022.6.9*/
int main(void)
{
   long MAX;
    printf("请输入要生成的学生数据个数:\n");
    fflush(stdin);
   	scanf("%ld",&MAX);
   	StudentList L=(StudentList) malloc(sizeof (StudentList));
   	L->data=(Student *) malloc((MAX+1)*sizeof (Student));
   	L->length=0;

start:    if(getFileList(L,MAX))
			printf("文件读取成功!\n");
    else
    {
        printf("文件读取失败!\n");
        exit(-1);
    }
    clock_t begin,end;
	char *key=(char *) malloc(MAX*sizeof (char));
	char choice_1,choice_3,choice_4;
	Status choice_2;

a:    printf("|—————请选择———————|\n");
	printf("|----------1.顺序查找----------|\n");
	printf("|----------2.二分查找----------|\n");
	printf("|---Powered by CaptainUniverse_|\n");
	printf("|———————★———————|\n\n");
    fflush(stdin);
	scanf("%c",&choice_1);
	if(choice_1!='1'&&choice_1!='2')
	{
		printf("输入有误!\n");
		goto a;
	}
	
b:    printf("|—————请选择———————|\n");
	printf("|--------1.直接插入排序--------|\n");
	printf("|--------2.选择排序------------|\n");
	printf("|--------3.快速排序------------|\n");
	printf("|--------4.改进冒泡排序--------|\n");
	printf("|---Powered by CaptainUniverse_|\n");
	printf("|———————★———————|\n\n");
	fflush(stdin);
	scanf("%d",&choice_2);
	if(choice_2!=1&&choice_2!=2&&choice_2!=3&&choice_2!=4)
	{
		printf("输入有误!\n");
		goto b;
	}
c:    printf("|—————请选择———————|\n");
	printf("|----------1.查找班号----------|\n");
	printf("|----------2.查找姓名----------|\n");
	printf("|---Powered by CaptainUniverse_|\n");
	printf("|———————★———————|\n\n");
	fflush(stdin);
	scanf("%c",&choice_3);
	if(choice_3!='1'&&choice_3!='2')
	{
		printf("输入有误!\n");
		goto c;
	}
		
	printf("请输入查找内容:\n"); 
	fflush(stdin);
    gets(key);
    
    begin=clock();
    if(choice_1=='1')
    {
		if(choice_3=='1')
			display(L,Sq_Search(L,key,by_class,choice_2),key);
		else if(choice_3=='2')
			display(L,Sq_Search(L,key,by_name,choice_2),key);
	}
	else if(choice_1=='2')
	{
		if(choice_3=='1')
			display(L,Binary_Search(L,key,by_class,choice_2),key);
		else if(choice_3=='2')
		{
			Bi_name_display(L,Binary_Search(L,key,by_name,choice_2),choice_2,key);
		}
	}	
	end=clock();
    printf("用时:%g ms\n\n",(double)(end-begin));
d:    printf("是否继续操作:\n");
    printf("1.继续\n");
    printf("2.退出\n");
    fflush(stdin);
    scanf("%c",&choice_4);
    if(choice_4=='1')
    	goto start;
    else if(choice_4=='2')
    {
    	printf("感谢您的使用!再见!\n");
		exit(0);
	}	
	else
	{
		printf("输入有误!\n");
		goto d;
	}
}
/*CaptainUniverse_ 2022.6.9*/

写在最后: 

2022.6.9 21:54

getFileList()函数写的太难看了 第一次写随机生成数据文件 等我有思路再改改

用了四种排序:直接插入排序、选择排序、快速排序、改进冒泡排序,两种查找:顺序查找、二分查找

每次操作后会显示过程所用时间 更直观比较出不同数据、排序法、查找法的时间效率

2022.6.12 18:37

无意打开优快云 竟发现有人给我打赏了 真的泪目 对我来说意义重大 太感谢了 @载驰|攻玉

更新了一下getFileList()函数 可以动态控制随机生成的信息数目了

但是它还是很丑 对于二分查找姓名后 班号>性别 输出还没想到更好的办法 现在是又创建了一张表 给新表按照班号排序 性别排序 

2022.6.29 1:30

版本大更新 应该是最终版本了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值