概述
一、实验要求
(1)对N个数进行排序并测试
(2)用直接插入排序、折半插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序这7种算法进行排序
(3)比较各种排序算法的时间复杂度和空间复杂度
(4)尝试算法的改进
二、实验过程
对N个数(N大于2000),从直接插入排序、折半插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序这7种算法中选取4种排序算法进行排序。
1.设计合适的数据结构存储这N个数。
2.对这N个数分别用下列三种情况进行测试:
(1)N个从小到大的有序整数
(2)N个从大到小的有序整数
(3)N个随机产生的无序数
3.比较各类排序算法的时间复杂度和空间复杂度。
4.对上述算法提出改进之处(创新思维)。
三、实验代码
选用的结构体是顺序表,其中的last其实在后面没有作用,只是用作与初始化用。
typedef int DataType;
typedef struct{
DataType data[MAXSIZE];
int last;
}node;
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAXSIZE 2001
typedef int DataType;
//结构体函数
typedef struct{
DataType data[MAXSIZE];
int last;
}node;
//初始化顺序表
void initlist(node *r){
r->last=0;
}
//无序版本的顺序表
void putNum(node *r){
initlist(r);
srand(time(0));
int i;
for(i=1;i<MAXSIZE;i++){
r->data[i]=rand();
}
}
//升序版本的顺序表
void putNumshen(node *r){
initlist(r);
int i;
for(i=1;i<MAXSIZE;i++){
r->data[i]=i;
}
}
//降序版本的顺序表
void putNumjiang(node *r){
initlist(r);
int i;
int n=MAXSIZE;
for(i=1;i<MAXSIZE;i++){
r->data[i]=n;
n--;
}
}
//测试使用,用于输出较少的测试
void shuchu(node r){
int i;
for(i=1;i<MAXSIZE;i++){
printf("%dn",r.data[i]);
}
printf("----------------------");
}
//直接插入排序的函数使用
void sort(node r,int n){
int i,j;
int sortComp=0;
int sortMove=0;
for(i=2;i<n;i++){
r.data[0]=r.data[i];
sortMove++;
j=i-1;
while(sortComp++,r.data[j]>r.data[0]){
r.data[j+1]=r.data[j];
sortMove++;
j--;
}
r.data[j+1]=r.data[0];
sortMove++;
}
// for(i=1;i<MAXSIZE;i++){
// printf("%dn",r.data[i]);
// }
printf("直接插入排序比较次数:%dn",sortComp);
printf("直接插入排序移动次数:%dn",sortMove);
// printf("n");
}
//二分插入排序的函数使用
void binasort(node r,int n){
int i,j,l,h,mid;
int binaComp=0;
int binaMove=0;
for(i=2;i<n;i++){
r.data[0]=r.data[i];
l=1;
h=i-1;
while(l<=h){
mid =(l+h)/2;
if(r.data[0]<r.data[mid]){
h=mid-1;
}else{
l=mid+1;
}
binaComp++;
}
for(j=i-1;j>=l;j--){
r.data[j+1]=r.data[j];
binaMove++;
}
r.data[l]=r.data[0];
binaMove++;
}
// for(i=1;i<MAXSIZE;i++){
// printf("%dn",r.data[i]);
// }
// printf("----------------------");
printf("二分插入排序比较次数:%dn",binaComp);
printf("二分插入排序移动次数:%dn",binaMove);
// printf("n");
}
//冒泡排序的函数使用
void bubblesort(node r,int n){
int i=1,tag,j;
int bubbleComp=0;
int bubbleMove=0;
node x;
do{
tag=0;
for(j=n;j>i;j--){
bubbleComp++;
if(r.data[j]<r.data[j-1]){
x.data[0]=r.data[j];
r.data[j]=r.data[j-1];
r.data[j-1]=x.data[0];
tag=1;
bubbleMove+=3;
}
}
i++;
}while(tag == 1 && i<=n);
// for(i=1;i<MAXSIZE;i++){
// printf("%dn",r.data[i]);
// }
// printf("---------------7-------");
printf("冒泡排序比较次数:%dn",bubbleComp);
printf("冒泡插入排序移动次数:%dn",bubbleMove);
// printf("n");
}
//简单插入排序的函数使用
void sisort(node r,int n){
int i,j,z;
node x;
int sisortComp=0;
int sisortMove=0;
for(i=1;i<n;i++){
z=i;
for(j=i+1;j<=n;j++){
if(sisortComp++,r.data[j]<r.data[z]){
z=j;
}
}
if(z!=i){
x.data[0]=r.data[i];
r.data[i]=r.data[z];
r.data[z]=x.data[0];
sisortMove+=3;
}
}
// for(i=1;i<MAXSIZE;i++){
// printf("%dn",r.data[i]);
// }
printf("简单选择排序比较次数:%dn",sisortComp);
printf("简单选择排序移动次数:%dn",sisortMove);
// printf("n");
}
int main(){
node r;
putNumjiang(&r);
// shuchu(r);
double s=clock();
sort(r,2000);
double e=clock();
printf("直接插入排序的时间为 %lf msn",e-s);
printf("------------------------------n");
s=clock();
binasort(r,2000);
e=clock();
printf("二分插入排序的时间为%lf msn",e-s);
printf("------------------------------n");
s=clock();
bubblesort(r,2000);
e=clock();
printf("冒泡排序的时间为%lf msn",e-s);
printf("------------------------------n");
s=clock();
sisort(r,2000);
e=clock();
printf("简单选择排序的时间为%lf ms",e-s);
}
实验步骤与算法描述
1.实验开始时,创建顺序表结构体;
2.初始化顺序表结构体,并且选择升序、降序、无序;
3.升序版本,for循环往顺序表添加数组的数据,每循环一次数据+1;
4.降序版本,for循环往顺序表添加数组的数据,每循环一次数据-1;
5.无序版本,使用srand(time(0))函数生成一个种子,保证数组中的数字都是不重复的。
6.设置double s=clock(),之后进行直接插入函数的(升序/降序/无序)排列,在函数中设置对比次数和移动次数,结束后设置double e=clock(),输出e-s得到直接插入函数的时间。
7.设置 s=clock(),之后进行折半插入排序的(升序/降序/无序)排列,在函数中设置对比次数和移动次数,结束后设置 e=clock(),输出e-s得到折半插入排序函数的时间。
8.设置s=clock(),之后进行冒泡排序函数的(升序/降序/无序)排列,在函数中设置对比次数和移动次数,结束后设置 e=clock(),输出e-s得到冒泡排序函数的时间。
9.设置 s=clock(),之后进行简单选择排序函数的(升序/降序/无序)排列,在函数中设置对比次数和移动次数,结束后设置 e=clock(),输出e-s得到简单选择排序函数的时间。
10.输出所有结果。
这里举例一下直接插入排序的实验流程图,各个的代码可能不太一样,按照实际代码更改。
4种算法在三种情况测试下的实验结果(比较次数、移动次数和运行耗时):
从小到大:
从大到小:
随机产生:
算法性能的比较
算法的改进意见
直接插入排序算法:将搜索和数据移动这二个步骤合并。每次a[i]先和前面一个数据a[i-1]比较,如果a[i] > a[i-1]说明a[1]到a[i]也是有序的,无须调整。否则就令j=i-1,x(标记)=a[i]。然后一边将数据a[j]向后移动一边向前搜索,当有数据a[j]<a[i]时停止并将x放到a[j + 1]处。
折半插入排序算法:当待排序列已是最佳次序时,只要将本次记录与有序序列的最后一个记录(即本次记录的前一个记录)比较,便可以结束本轮排序,无需进行后续运算。
冒泡排序算法:若发现从某个位置x开始,不再进行记录交换,就说明r[i+1]到r[n-1]已经排好序,因此下一趟比较只要进行到位置x就行。冒泡算法改进,用变量x记录数据最后一次交换位置,下次再从x开始比较就可以了。
最后
以上就是含糊衬衫为你收集整理的【数据结构】排序-直接插入排序 折半插入排序 冒泡排序 简单选择排序的实验应用的全部内容,希望文章能够帮你解决【数据结构】排序-直接插入排序 折半插入排序 冒泡排序 简单选择排序的实验应用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复