数据结构--排序算法演示


备注:由于粘贴格式的问题,程序流程图、运行结果可见资源包(免费)。

题目:设计内容九 排序算法演示

问题描述】

在信息处理过程中,最基本的操作是查找。从查找来说,效率最高的是折半查找,折半查找的前提是所有的数据元素(记录)是按关键字有序的,因此需要先将一个无序的序列转变为一个有序的序列。试写一个程序,演示对待排序序列用不同的排序方法进行排序操作。

【基本要求】

	实现以下排序算法:
	1.直接插入排序
	2.希尔排序
	3.起泡排序
	4.快速排序
	5.简单选择排序
	6.堆排序
	要求待排序表的表长不小于10;至少用5组不同的输入数据比较以上排序算法;比较的指标为关键字的比较次数和记录的移动次数(1次记录的交换记为3次移动)。

【测试数据】

可以考虑几组数据的典型性,如,正序、逆序和不同程度的乱序,精心设计实验数据。

【实现提示】

待排序表的数据类型见教材P264。在已知算法中适当位置插入对关键字的比较次数和记录的移动次数计数操作。注意设计程序的输出结果,便于对比。

目   录
第一章课程设计概述
	1.1课程设计的目的
	1.2课程设计的任务及简介
第二章  需求分析
第三章  数据结构设计
第四章  算法设计
	4.1 菜单模块
	4.1.1模块功能简介
	4.1.2模块流程图
	4.1.3模块代码分析和注释
	4.1.4模块运行结果截图
	4.2 输入模块
	4.2.1模块功能简介
	4.2.2模块流程图
	4.2.3模块代码分析和注释
	4.2.4模块运行结果截图
	4.3 输出模块
	4.3.1模块功能简介
	4.3.2模块流程图
	4.3.3模块代码分析和注释
	4.3.4模块运行结果截图
	4.4 计数模块
	4.4.1模块功能简介
	4.4.2模块代码分析和注释
	4.4.3模块运行结果截图
	4.5 直接插入排序模块
	4.5.1模块功能简介
	4.5.2模块流程图
	4.5.3模块代码分析和注释
	4.5.4模块运行结果截图
	4.6 希尔排序模块
	4.6.1模块功能简介
	4.6.2模块流程图
	4.6.3模块代码分析和注释
	4.6.4模块运行结果截图
	4.7 起泡排序模块
	4.7.1模块功能简介
	4.7.2模块流程图
	4.7.3模块代码分析和注释
	4.7.4模块运行结果截图
	4.8 快速排序模块
	4.8.1模块功能简介
	4.8.2模块流程图
	4.8.3模块代码分析和注释
	4.8.4模块运行结果截图
	4.9 简单选择排序模块
	4.9.1模块功能简介
	4.9.2模块流程图
	4.9.3模块代码分析和注释
	4.9.4模块运行结果截图
	4.10 堆排序模块
	4.10.1模块功能简介
	4.10.2模块流程图
	4.10.3模块代码分析和注释
	4.10.4模块运行结果截图
	4.11 各排序方法比较模块
	4.11.1模块功能简介
	4.11.2模块代码分析和注释
	4.11.2模块运行结果截图
第五章 第二轮数据测验
第六章 课程设计总结 
第七章 参考文献

第一章课程设计概述

1.1课程设计的目的

1.1.1熟悉部分排序算法的运用

1.1.2比较部分排序算法的效率(比较和移动的次数)

1.2课程设计的任务及简介

1.2.1在信息处理过程中,最基本的操作是查找。从查找来说,效率最高的是折半查找,折半查找的前提是所有的数据元素(记录)是按关键字有序的,因此需要先将一个无序的序列转变为一个有序的序列。试写一个程序,演示对待排序序列用不同的排序方法进行排序操作。

【基本要求】

	实现以下排序算法:
	1.直接插入排序
	2.希尔排序
	3.起泡排序
	4.快速排序
	5.简单选择排序
	6.堆排序
要求待排序表的表长不小于10;至少用5组不同的输入数据比较以上排序算法;比较的指标为关键字的比较次数和记录的移动次数(1次记录的交换记为3次移动)。

【测试数据】

可以考虑几组数据的典型性,如,正序、逆序和不同程度的乱序,精心设计实验数据。

【实现提示】

待排序表的数据类型见教材P264。在已知算法中适当位置插入对关键字的比较次数和记录的移动次数计数操作。注意设计程序的输出结果,便于对比

第二章 需求分析

2.1 用户操作界面形式;包括输入数据的格式;输出数据的格式:

1)在主函数中利用for循环和switch来设计菜单;
(2)在主函数输入需要测试的数据组数和数据长度;
(3)创建一个输入函数,供其它函数调用;
(4)创建一个输出函数,供其他函数调用;

2.2 程序功能:

(1)利用直接插入排序、希尔排序、起泡排序、快速排序、简单选择排序、堆排序对数据进行排序;
(2)统计上述算法比较和移动的次数并进行比较;

2.3 测试数据:

      输入要排序的组数:6
      输入该组元素的长度:12
输入一组乱序数据:12 3 6 4 8 10 11 1 5 7 2 9
该数据部分将在第四章,算法设计中进行测试;

第三章 数据结构设计

3.1程序的数据结构:

#define maxsize 20   //定义一个作业里的小顺序表的最大长度
typedef int Keytype;    //定义关键字类型为整数类型
typedef struct
{
	Keytype key;              //关键字项
}Redtype;

typedef struct
{
	Redtype r[maxsize+1];   //r[0]闲置或用作哨兵单元
	int length;       //顺序表长度
	int compare;      //比较次数,为全局变量
	int move;         //移动次数,为全局变量
}Sqlist;

3.2程序功能模块的划分:
void count(Sqlist &L);        //记录查找次数
void enter(Sqlist &L);    //输入
void print(Sqlist &L);            //输出
void insertsort(Sqlist &L);    //直接插入排序
void shellinsert(Sqlist &L,int dk);  //希尔插入
void shellsort(Sqlist &L,int dlta[],int t);      //希尔排序
void bubble(Sqlist &L,int n);       //冒泡排序
int partition(Sqlist &L,int low,int high);      //枢轴记录位置,在它前后的数均不大于(或小于)它
void Qsort(Sqlist &L,int low,int high) ;         //对顺序表L中的子序列[low...high]作快速排列
void Quicksort(Sqlist &L);        //快速排序 
void selectsort(Sqlist &L);     //简单选择选择
void Headadjust(Sqlist &L,int s,int m);    //堆调整
void Headsort(Sqlist &L);                  //堆排序
void main( )                               //主函数

第四章 算法设计

4.1 菜单模块

4.1.1模块功能简介

菜单模块提供选择菜单,用户可以根据操作需要选择所要操作的菜单。

1:直接插入排序;          选2:希尔排序;  
	选3:起泡排序 ;            选4:快速排序;    
	选5:简单选择排序 ;        选6:堆排序 ;      
	选7:各排序方法比较 ;       
	选8:进入下一步 ,若for循环未结束,则进行下一组数据的输入,
	若for循环结束,则程序运行结束;

4.1.2模块流程图

4.1.3模块代码分析和注释

void main()
{
Sqlist L;
    Sqlist A,B,C,D,E,F;
    int m;	
	char z;
	int dt[3]={5,3,1};
	printf("请输入要排序的组数: ");
    scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int n=1;
		printf("\n*********************************************************\n");       //输入*
		printf("请输入第%d组数据信息 :\n\n",i);
		printf("请输入数据长度(>10): ");
		scanf("%d",&L.length);
		printf("\n");
		enter(L);
		A=B=C=D=E=F=L;       //初始化
		while(n==1)
		{
			printf("\n***********************************************************");    //输入*
			printf("\n*                         菜    单                        *");
			printf("\n***********************************************************");    //输入* 
			printf("\n            1.直接插入排序          2.希尔排序     \n");
			printf("\n            3.起泡排序              4.快速排序     \n");
			printf("\n            5.简单选择排序          6.堆排序       \n");
			printf("\n            7.各排序方法比较        8.进入下一步   \n");
			printf("\n***********************************************************");
			printf("\n请选择(1~7):\n");
			z=getch();
			switch(z)
			{  
			case'1':
				insertsort(A);    //直接插入排序函数调用
				break;
			case'2':
				shellsort(B,dt,3);  //希尔排序函数调用
				break;
			case'3':
				bubble(C,L.length);    //起泡排序函数调用
				break;
			case'4':
				Quicksort(D);     //快速排序函数调用
				break;
			case'5':
				selectsort(E);    //简单选择排序函数调用
				break;
			case'6':
				Headsort(F);     //堆排序函数调用
				break;
			case'7':
				printf("\n\n**********************各排序方法比较***********************\n\n");
				//各种排序比较和移动次数的综合比较
				printf("直接插入排序 :   ");
				count(A);
				printf(" 希 尔 排 序 :   ");
				count(B);
				printf(" 起 泡 排 序 :   ");
				count(C);
				printf(" 快 速 排 序 :   ");
				count(D);
				printf("简单选择排序 :   ");
	count(E);
				printf("  堆  排  序 :   ");
				count(F);
				break;
			default: n=0;
			}
		}
	}
}

4.1.4模块运行结果截图

4.2 输入模块

(1)模块功能简介:用于数据的数出,供其他函数调用;
(2)模块流程图

4.2.3模块代码分析和注释

void enter(Sqlist &L)    //输入
{
	printf("请输入数据内容: ");
	for(int i=1;i<=L.length;i++)  //L.length为数据长度
		scanf("%d",&L.r[i].key);
	printf("\n");
}

4.2.4模块效果截图

4.3 输出模块

(1)模块功能简介:用于其他数据的输出,供其他函数调用;
(2)模块流程图
4.3.3模块代码分析和注释

void print(Sqlist &L)      //输出
{
	printf("              ");
	for(int k=1;k<=L.length;k++)     //L.length为数据长度
		printf(" %d  ",L.r[k].key);
	printf("\n\n");
}

4.3.4模块效果截图

4.4 计数模块

(1)模块功能简介:用于统计各算法的比较和移动次数;
(2)模块代码分析和注释

   void count(Sqlist &L)
{
	printf("  比较次数为: %d 移动次数为: %d\n",L.compare,L.move);
}

4.4.3模块效果截图

4.5 直接插入排序模块

(1)模块功能简介:
利用直接插入法对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()数进行输出;
(2)模块流程图
4.5.2模块代码分析和注释

void insertsort(Sqlist &L)       //直接插入排序
{
	int a;
	L.compare=0;
	L.move=0;
	printf("\n  原数据元素  :   \n");
	print(L);
	printf("直接插入排序 :  \n");
	for (int i=2; i<=L.length; i++ )
	{
		if(L.r[i].key < L.r[i-1].key)      // 将 L.r[i] 插入有序子表
		{
			L.compare++;
			L.r[0]=L.r[i];         // 哨兵
			L.move++;
			L.r[i]=L.r[i-1];
			L.move++;
			for (int j=i-2;L.r[0].key < L.r[j].key;j--,L.compare++)
			{				
				L.r[j+1] = L.r[j];        //记录后移	
				L.move++;
			}
			L.r[j+1] = L.r[0];     // 插入到正确位置
			L.move++;	
		} 
		print(L);
		L.compare++;
	}
	count(L);
	printf("\n请按任意键继续...\n");
	a=getch();
} // InsertSort*/	

4.5.3模块效果截图

4.6 希尔排序模块

(1)模块功能简介:
利用希尔排序对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()函数进行输出;
(2)模块流程图
(3)模块代码分析和注释

void shellinsert(Sqlist &L,int dk)  //希尔排序
{
	L.compare=0;
	L.move=0;
	for (int i=dk+1; i<=L.length; ++i )
	{
		if(L.r[i].key< L.r[i-dk].key)  // 需将L.r[i]插入有序增量子表
		{ 
			L.compare++;
			L.r[0] = L.r[i]; 
			L.move++;
			for(int j=i-dk; j>0 && L.r[0].key < L.r[j].key; j-=dk )
			{
				L.compare++;
				L.r[j+dk] = L.r[j];      // 记录后移,查找插入位置
				L.move++;
			}
			L.compare++;
			L.r[j+dk] = L.r[0];     // 插入
			L.move++;	
		} // if
		L.compare++;
	}
	print(L);	
}	

void shellsort(Sqlist &L,int dlta[],int t)  // 按增量序列 dlta[0..t-1] 对顺序表L作希尔排序
{
	int b;
	printf("\n  原数据元素  :   \n");
	print(L);
	printf("  希 尔 排 序 :   \n");
	for (int k=0; k<t; k++) 	// 一趟增量为 dlta[k] 的插入排序
		shellinsert(L, dlta[k]);
	count(L);
	printf("\n请按任意键继续...\n");
	b=getch();
} // ShellSort

(4)模块效果截图

4.7 起泡排序模块

(1)模块功能简介:
利用起泡排序对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()函数进行输出;
(2)模块流程图
(3)模块代码分析和注释

void bubble(Sqlist &L,int n)       //起泡排序 
{
	L.compare=0;
	L.move=0;
	int c;
	int i,j,temp;
	printf("\n  原数据元素  :   \n");
	print(L);
	printf(" 起 泡 排 序 :  \n");	
	for(i=1;i<=n-1;i++)
	{
		for(j=1 ;j<=n-i;j++)	
		{
			L.compare++;
            if(L.r[j].key>L.r[j+1].key)
			{			
				temp=L.r[j].key;
				L.r[j].key=L.r[j+1].key;
				L.r[j+1].key=temp;
				L.move=L.move+3;
			}		
		}		
	  print(L); 
	}
	count(L);
	printf("\n请按任意键继续...\n");
	c=getch();
}

(4)模块效果截图

4.8 快速排序模块

(1)模块功能简介:
利用快速排序方法对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()函数进行输出;
(2)模块流程图
(3)模块代码分析和注释
int partition(Sqlist &L,int low,int high) //枢轴记录位置,在它前后的数均不大于(或小于)它
//交换顺序表L中的字表r[low…high]的记录,枢轴记录到位,并返回其所在位置

{	
	int pivotkey;
	L.r[0]=L.r[low];
	L.move++;
	pivotkey=L.r[low].key;
	while(low<high)
	{	
		
		while(low<high&&L.r[high].key>=pivotkey)
		{
			L.compare++;
			high--;
		}
		L.r[low]=L.r[high];	
	 	L.move++;
		while(low<high&&L.r[low].key<=pivotkey)	
		{
			L.compare++;
			low++;
		}
		L.r[high]=L.r[low];	
	}
	L.r[low]=L.r[0];
	L.move++;
	print(L);
	return low;
}
void Qsort(Sqlist &L,int low,int high)    //对顺序表L中的子序列[low...high]作快速排列
{
	
	int pivotloc;
	if(low<high)
	{
		pivotloc=partition(L,low,high);
		Qsort(L,low,pivotloc-1);
		Qsort(L,pivotloc+1,high);
	}
	
}
void Quicksort(Sqlist &L)            //快速排序
{
	int d;
	L.move=0;
	L.compare=0;
	printf("\n 原数据元素 :   \n");
	print(L);
	printf(" 快 速 排 序 :  \n");
	Qsort(L,1,L.length);
	count(L);	
	printf("\n请按任意键继续...\n");
	d=getch();
}

4.8.4模块效果截图

4.9 简单选择排序模块

(1)模块功能简介:
利用简单选择排序对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()函数进行输出;
(2)模块流程图
(3)模块代码分析和注释

void selectsort(Sqlist &L)     //简单选择排序
{
	L.compare=0;
	L.move=0;
	int i,j,temp,small;
int e;
	printf("\n 原数据元素 :   \n");
	print(L);
	printf("简单选择排序 :  \n");
	for(i=1;i<L.length;i++)
	{	
		small=i;
		for(j=i+1;j<=L.length;j++)
		{
			L.compare++;
			if(L.r[small].key>L.r[j].key)
				small=j;	
		}				
		if(small!=i)
		{
			temp=L.r[i].key;
			L.r[i].key=L.r[small].key;
			L.r[small].key=temp;	
		}
		L.move=L.move+3;
		print(L);
	}
	count(L);
	printf("\n请按任意键继续...\n");
	e=getch();
}

(4)模块效果截图

4.10 堆排序模块

(1)模块功能简介:
利用堆排序对数据进行排序,并利用cout()函数统计比较和移动次数,利用print()函数进行输出;
(2)模块流程图
(3)模块代码分析和注释

void Headadjust(Sqlist &L,int s,int m)    //堆调整
{
	L.r[0]=L.r[s];
	L.move++;
	for(int j=2*s;j<=m;j*=2)
	{
		if(j<m&&L.r[j].key<L.r[j+1].key)
		{
			L.compare++;
			j++;
		}
		L.compare++;
		if(L.r[0].key>L.r[j].key)
		{
			L.compare++;
			break;
		}
		L.compare++;
		L.r[s]=L.r[j];
		L.move++;
		s=j;
	}
	L.r[s]=L.r[0];
	L.move++;
	print(L);
}
void Headsort(Sqlist &L)                 //堆排序
{
	int temp;
	int f;
	L.compare=0;
	L.move=0;
	printf("\n 原数据元素 :   \n");
	print(L);
	printf("  堆  排  序 :  \n");
	for(int i=L.length/2;i>0;--i)
		Headadjust(L,i,L.length);
	for(i=L.length;i>1;--i)
	{
		temp=L.r[1].key;
		L.r[1].key=L.r[i].key;
		L.r[i].key=temp;
		Headadjust(L,1,i-1);
		L.move=L.move+3;
	}	
	count(L);
	printf("\n请按任意键继续...\n");
	f=getch();
}

(4)模块效果截图

4.11 各排序方法比较模块

(1)模块功能简介:
将各排序方法比较和移动的次数综合起来输出,进行比较;
(2)模块代码分析和注释
代码位于主函数中,其代码部分:

		case'7':
				printf("\n\n**********************各排序方法比较***********************\n\n");
				//各种排序比较和移动次数的综合比较
				printf("直接插入排序 :   ");
				count(A);                  //直接插入排序的比较和移动次数
				printf(" 希 尔 排 序 :   ");
				count(B);                  //希尔排序的比较和移动次数
				printf(" 起 泡 排 序 :   ");
				count(C);                  //起泡排序的比较和移动次数
				printf(" 快 速 排 序 :   ");
				count(D);                  //快速排序的比较和移动次数
				printf("简单选择排序 :   ");
				count(E);                  //简单选择排序的比较和移动次数
				printf("  堆  排  序 :   ");
				count(F);                  //堆排序的比较和移动次数
				break;
			default: n=0;

(3)模块效果截图

第五章 第二组数据测验

输入第二组数据长度:12 
输入第二组逆序数据:12 11 10 9 8 7 6 5 4 3 2 1

运行结果截图:

结果分析:

1)从乱序数据来看:希尔排序和快速排序的效率较高;
(2)从逆序数据来看:希尔排序和快速排序和简单选择排序的效率较高;
(3)从正序数据来看:直接插入排序,希尔排序,起泡排序移动次数均为0,直接插入排序和希尔排序效率较高;

第六章 课程设计总结

通过这次的课程设计,加深我对这些排序方法的进一步理解,如何比较,如何移动进行排序,并且对这些排序方法的比较和移动进行了统计,对其效率比较也有了进一步的理解;也进一步加深了我的编程能力,如何去排版,如何去调用,如何去实现递归,如何去设计界面,如何让编程语句更简洁,以及对一些小知识点运用的回顾及巩固;

第七章 参考与文献

【1】 严蔚敏, 吴伟民. 数据结构(C语言版). 北京: 清华大学出版社, 1997.4

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值