内部排序算法的实现与比较

合集下载

数据结构-内排序

数据结构-内排序

Shell排序的性能分析
Shell排序的时间复杂度在O(nlog2n)和O(n2)间, Knuth的 统计结论是,平均比较次数和记录平均移动次数在n1.25与 1.6n1.25之间
Shell排序是一种不稳定的排序方法
最后谈一下delta的取法。 Shell最初的方案是delta=n/2, delta=delta/2,直到delta=1。Knuth的方案是delta=delta/3 +1。其它方案有:都取奇数为好;或delta互质为好等等。 而使用象1, 2, 4, 8, …或1, 3, 6, 9, …这样的增量序列就不太 合适,因为这样会使几个元素多次被分到一组中,从而造 成重复排序,产生大量无用的比较操作
另外,在无序子表中向前移动的过程中,如果没 有交换元素,则说明无序子表已有序,无须再做 排序
24
冒泡排序算法实现
1 void bubble_sort(RecType R[ ], int n) { 2 //待排序元素用一个数组R表示,数组有n个记录
3 int i, j; 4 bool swap=TRUE; //判断无序子表是否已有序的变量
内排序和外排序 按照排序过程中使用内、外存的不 同将排序方法分为内排序和外排序。若待排序记录全 部在内存中,称为内排序;若待排序记录的数量很大, 以致内存一次不能容纳全部记录,在排序过程中需要 进行内、外存交换,称为外排序。本章仅讨论内排序
内排序可分为五大类:插入排序、交换排序、选择排 序、归并排序和基数排序
直接插入排序(straight insert sort) 折半插入排序(binary insert sort) Shell排序(Shell sort)
10
10.2.1 直接插入排序举例

数据结构-第十章-内部排序

数据结构-第十章-内部排序

0
1
2
3
4
5
6
7
8
i=5
MAXINT 49 2 3
MAXINT 49 6 3 MAXINT 49 6 3 MAXINT 49 6 8
38 1
38 1 38 1 38 1
65 97 5 0
65 5 65 5 65 5 97 0 97 0 97 0
76 4
76 4 76 4 76 4
13
27
49
i=6



最坏情况下,待排记录按关键字非递增有序 排列(逆序)时,第 i 趟时第 i+1 个对象 必须与前面 i 个对象都做排序码比较, 并且 每做1次比较就要做1次数据移动。总比较 次 数 为 (n+2)(n-1)/2 次 , 总 移 动 次 数 为 (n+4)(n-1)/2。 在平均情况下的排序码比较次数和对象移 动次数约为 n2/4。因此,直接插入排序的 时间复杂度为 O(n2)。 直接插入排序是一种稳定的排序方法。
折半插入排序 (Binary Insertsort)
基本思想 既然每个要插入记录之前的纪录 已经按关键字有序排列,在查找插入位 臵时就没有必要逐个关键字比较,可以 使用折半查找来实现。由此进行的插入 排序称之为折半插入排序。
折半插入排序的算法
void BInsertSort (SqList &L){ for (i=2;i<=L.length;++i){ L.r[0]=L.r[i]; low=1;high=i-1; //查找范围由1到i-1 while(low<=high){ m=(low+high)/2; if LT(L.r[0].key,L.r[m].key) high=m-1; else low=m+1; }//while 折半查找 for (j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j]; //折半查找结束后high+1位臵即为插入位臵 L.r[high+1]=L.r[0]; }//for }//BInsertSort

河北工业大学-数据结构实验报告-内部排序算法效率比较平台的设计与实现

河北工业大学-数据结构实验报告-内部排序算法效率比较平台的设计与实现

实验五内部排序算法效率比较平台的设计与实现1.试验内容1、问题描述各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。

设计和实现内部排序算法效率比较平台,通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观的感受。

2、基本要求(1)对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

(2)待排序的表长不小于100;其中的数据要用伪随机数产生程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)。

(3)最后要对结果作出简单分析,包括对各组数据得出结果波动大小的解释。

3、测试数据由随机数产生器生成。

4、实现提示主要工作是设法在已知算法中的适当位置插入对关键字的比较次数和移动次数的计数操作。

程序还可以考虑几组数据的典型性,如,正序、逆序和不同程度的乱序。

注意采用分块调试的方法。

2.试验目的掌握多种排序方法的基本思想,如直接插入、冒泡、简单选择、快速、堆、希尔排序等排序方法,并能够用高级语言实现。

3.流程图4.源程序代码#include<iostream.h>#include<string.h>#include<stdlib.h>#define le 100struct point{char key[11];};//冒泡法void maopao(point c[]){point a,b[le];int i,j,jh=0,bj=0,q;for(i=0;i<le;i++){b[i]=c[i];};for(i=0;i<le;i++){for(j=le-1;j>i;j--){bj=bj+1;q=strcmp(b[i].key,b[j].key);if(q==1){a=b[i];b[i]=b[j];b[j]=a;jh=jh+3;};};};cout<<"冒泡法:"<<endl<<"完成的序列如下:"<<endl;for(i=0;i<le;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<bj<<"次,进行交换"<<jh<<"次"<<endl<<"***************************"<<endl;};//直接插入排序void zhijiecharu(point c[]){point b[le+1];int i,j,jh=0,bj=0,q;for(i=0;i<le;i++){b[i+1]=c[i];};for(i=2;i<=le+1;i++){q=strcmp(b[i].key,b[i-1].key);bj=bj+1;if(q==-1){b[0]=b[i];b[i]=b[i-1];jh=jh+2;q=strcmp(b[0].key,b[i-2].key);bj=bj+1;for(j=i-2;q==-1;j--){b[j+1]=b[j];jh=jh+1;q=strcmp(b[0].key,b[j-1].key);bj=bj+1;};b[j+1]=b[0];jh=jh+1;};};cout<<"直接插入排序:"<<endl<<"完成的序列如下:"<<endl;for(i=1;i<le+1;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<bj<<"次,进行交换"<<jh<<"次"<<endl<<"***************************"<<endl;};//void shellinsert(point c[],int dk,int d[]){int j,i,q;point a;for(i=dk+1;i<le+1;i++){q=strcmp(c[i].key,c[i-dk].key);d[0]=d[0]+1;if(q==-1){a=c[i];q=strcmp(a.key,c[i-dk].key);d[0]=d[0]+1;d[1]=d[1]+1;for(j=i-dk;j>0&&q==-1;j=j-dk){c[j+dk]=c[j];d[1]=d[1]+1;q=strcmp(a.key,c[j-dk].key);};c[j+dk]=a;d[1]=d[1]+1;};};};void shellsort(point c[],int dlta[],int t){int k,d[2],i;d[0]=0;d[1]=0;point b[le+1];for(k=0;k<le;k++){b[k+1]=c[k];};for(k=0;k<t;k++)shellinsert(b,dlta[k],d);cout<<"希尔排序:"<<endl<<"完成的序列如下:"<<endl;for(i=1;i<le+1;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<d[0]<<"次,进行交换"<<d[1]<<"次"<<endl<<"***************************"<<endl;};//希尔排序void xier(point c[]){int dlta[20],t,i;t=le/2;for(i=0;i<20;i++){dlta[i]=t+1;if(t==0)break;t=t/2;};t=i+1;shellsort(c,dlta,t);};//简单选择排序void jiandanxuanze(point c[]){point a,b[le];int i,j,jh=0,bj=0,q,w;for(i=0;i<le;i++){b[i]=c[i];};for(i=0;i<le-1;i++){q=i;for(j=i+1;j<le;j++){bj=bj+1;w=strcmp(b[q].key,b[j].key);if(w==1)q=j;};if(q==i)continue;else {a=b[i];b[i]=b[q];b[q]=a;jh=jh+3;};};cout<<"简单选择排序排序:"<<endl<<"完成的序列如下:"<<endl;for(i=0;i<le;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<bj<<"次,进行交换"<<jh<<"次"<<endl<<"***************************"<<endl;};int partition(point c[],int low,int high,int d[]){point a,b;int jh=0,bj=0,q;a=c[low];while(low<high){q=strcmp(c[high].key,a.key);d[0]=d[0]+1;while(low<high&&q!=-1){high--;q=strcmp(c[high].key,a.key);d[0]=d[0]+1;};b=c[low];c[low]=c[high];c[high]=b;d[1]=d[1]+3;q=strcmp(c[low].key,a.key);d[0]=d[0]+1;while(low<high&&q!=1){low++;q=strcmp(c[low].key,a.key);d[0]=d[0]+1;};b=c[low];c[low]=c[high];c[high]=b;d[1]=d[1]+3;};return(low);};void qsort(point c[],int low,int high,int d[]){int pivotloc;if(low<high){pivotloc=partition(c,low,high,d);qsort(c,low,pivotloc-1,d);qsort(c,pivotloc+1,high,d);};};//快速排序void kuaisu(point c[]){point b[le];int i,d[2];d[0]=0;d[1]=0;for(i=0;i<le;i++){b[i]=c[i];};qsort(b,0,le-1,d);cout<<"快速排序:"<<endl<<"完成的序列如下:"<<endl;for(i=0;i<le;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<d[1]<<"次,进行交换"<<d[0]<<"次"<<endl<<"***************************"<<endl;};void diu(point b[],int we,int *jh,int *bj){point a;int i,q;for(i=we/2-1;i>=0;i--){q=strcmp(b[i].key,b[2*i].key);*bj=*bj+1;if(q==-1){a=b[i];b[i]=b[2*i];b[2*i]=a;*jh=*jh+3;};if(2*i+1<we){q=strcmp(b[i].key,b[2*i+1].key);*bj=*bj+1;if(q==-1){a=b[i];b[i]=b[2*i+1];b[2*i+1]=a;*jh=*jh+3;};};};a=b[we-1];b[we-1]=b[0];b[0]=a;*jh=*jh+3;};//堆排序void diup(point c[]){point b[le];int i,jh=0,bj=0,*j,*bl;j=&jh;bl=&bj;for(i=0;i<le;i++){b[i]=c[i];};for(i=le;i>1;i--){diu(b,i,j,bl);};cout<<"堆排序:"<<endl<<"完成的序列如下:"<<endl;for(i=0;i<le;i++){cout<<b[i].key<<" ";};cout<<endl<<"共进行比较"<<bj<<"次,进行交换"<<jh<<"次"<<endl<<"***************************"<<endl;};void main(){int i,j,n=10,ans,an;char b[]="abcdefghijklmnopqrstuvwxyz";point a[le];for(i=0;i<le;i++){n=10;an=rand()*(n-1)/RAND_MAX+1;n=26;for(j=0;j<an;j++){ans=rand()*(n-0)/RAND_MAX+0;a[i].key[j]=b[ans];};a[i].key[j]='\0';};for(i=0;i<le;i++){cout<<a[i].key<<endl;};zhijiecharu(a);maopao(a);xier(a);jiandanxuanze(a);kuaisu(a);diup(a);}参考自百度文库5.实验结果运行结果如下:直接插入排序:完成的序列如下:***************************冒泡法:完成的序列如下:***************************希尔排序:完成的序列如下:*************************** 简单选择排序排序:完成的序列如下:*************************** 快速排序:完成的序列如下:*************************** 堆排序:完成的序列如下:。

第三章内部排序算法比较

第三章内部排序算法比较

第三章内部排序算法比较3.1. 问题描述3.1.1 题目内容设计程序实现六种方法的内部排序:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

并对各个内部排序算法进行实测比较。

3.1.2 基本要求程序分别对六种常用的内部排序算法进行实测比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

待排序表的表长不小于100,其中数据要用随机数产生程序产生,要求用多组不同的输入数据进行比较,比较的指标为:有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次的移动)。

3.1.3 待测试数据因为所产生的数据是随机数,所以只需要用户输入要产生的随机数的个数。

所以可根据需要设置以下一组数:5,10,50,300,1000,7000,20000,50000。

3.2. 需求分析3.2.1 程序的基本功能首先用户输入要测试的随机数的个数,然后可以进行各个选项对数据进行不同的测试,程序能分别输出用起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序所用的移动关键字的步数,以便比较各个排序算法的效率。

3.2.2 输入值的形式和范围程序设定输入的整型数据在100000之内。

3.2.3 输出形式程序将产生的随机数以数组的形式储存,并在屏幕上依次输出,排序后得到的有序数组也同样依次输出,同时输出跟踪的来的总移动步数。

3.2.4 测试数据要求在调试时,为了能方便判断得出的结果是否正确可使用数量小的随机数,如3、4、5。

在调试确定算法能得出正确结果后测试数据要求每组随机数的个数应大于100,最好更长,这样才能更加容易得出各个排序算法在时间上的不同。

3.3. 概要设计3.3.1 主程序流程及模块调用关系(1)主程序流程图:一. 产生随机数。

二. 各个排序算法图 3-1 程序流程图(2)模块调用关系图见下页:图 3-23.3.2 核心的粗线条伪码算法设置一个类class Algorithm{……..将各个排序算法的函数作为类中的构造函数……..}A;Algorithm Sorting( )1. 输入随机数的个数N;2. 调用随机数产生函数产生个N随机数并储存到Array[1]~~Array[N]中.3. 输入选择功能4.switch(c){case '1':调用起泡法对所产生的随机数进行排序;case '2':调用直接插入法对所产生的随机数进行排序;case '3':调用简单选择法对所产生的随机数进行排序;case '4':调用快速排序法对所产生的随机数进行排序;case '5':调用Shell排序对所产生的随机数进行排序;case '6':调用堆排序对所产生的随机数进行排序;case '7':产生下一组随机数据case '8':结束并退出程序3.4. 详细设计3.4.1 实现概要设计的数据类型.定义一个类,将每个算法都现在该类中:Class Algorithm{Public:Bubblesort(){……….}StraightInsertsort(){……….}Selectsort(){……….}Quiksort(){……….}Shellsort(){……….}Heapesort(){……….}}A;3.4.2 每个操作的伪码算法.(1).起泡法排序伪码算法:Algorithm BubbleSort( ){while(k>1){//i>1表明上一趟曾进行过记录交换设定一个记录最后一次交换位置的整型int lastExchangeIndex=1;for(int j=1;j<k;j++){作循环当后一个元素小于前一个时L.elem[j+1].key<L.elem[j].key{相互交换元素的值.记录交换的元素的位置}将一趟排序中无序序列中最后一个记录的位置传递给k,做下一次循环(2).直接插入排序的伪算法:Algorithm InsertSort()for(int i=2;i<=L.length;++i)判断如果第i个元素的值小于第i-1元素的值时{ 需将第i个元素插入有序子表将i元素复制为哨兵for(int j=i-1;L.elem[0].key<L.elem[j].key;--j)将元素记录后移然后将哨兵插入到正确位置}(3).Shell排序伪算法Algorithm ShellSort(){设置一个整型变量福初始值为5(dlta=5; ){ 做运算dlta = dlta/3+1;调用ShellInsert函数}当设置的整型变量大于1;ShellInsert( ) //ShellInsert函数{for(int i=dk+1;i<=L.length;++i)if(L.elem[i].key<L.elem[i-dk].key){ //需将L.elem.[i]插入有序增量子表L.elem[0]=L.elem[i];//暂存在L.elem.[0]int j=i-dk;do{ L.elem[j+dk] = L.elem[j];j = j - dk;}while(j > 0&&L.elem[0].key < L.elem[j].key); //记录后移,查找插入位置插入操作L.elem[j+dk]=L.elem[0];}(4). 快速排序伪算法:Algorithm QuikSort(){判断需要排序的数组长度,如果大于1{调用Partition函数,将Low 到Hight一分为二分别调用QSort函数,分别对高低子表进行递归排序} }Partition(sqlist &R,int low,int high) //划分函数{//对记录子序列R[low....high]进行一趟快速排序,并返回枢轴记录所在位置,//使得在它之前的记录的关键字均不大于它的关键字,在它之后的记录的关键//字均不小于它的关键字将枢轴记录移至数组的闲置地方;枢轴记录关键字;从表的两端交替地向中间扫描;将比枢轴记录小的记录移到底端将比枢轴记录大的记录移到高端枢轴记录移到正确位置(R.elem[low] = R.elem[0])返回枢轴的位置return low}void QSort(sqlist &R,int low,int high) 函数对记录序列R[s....t]进行快速排序{ 如果子表长度大于1{ 调用Partition对R[s...t]进行一次划分,并返回枢轴位置对底端子序列递归排序(QSort(R,low,pivotloc-1) ).对高断子序列递归排序(QSort(R,pivotloc+1,high) ).}3.4.3 主程序和其它模块的伪码算法.Algorithm main( )1. 函数运行,并先后调用菜单函数和随机数产生函数2. 进入while循环,再次调用菜单函数3.进入如下一个Switch语句,对各个功能进行调用switch(c){ case '1':调用起泡法对所产生的随机数进行排序;case '2':调用直接插入法对所产生的随机数进行排序;……….case '6':调用堆排序对所产生的随机数进行排序;case '7':产生下一组随机数据case '8':结束并退出程序3.5. 调试分析3.5.1 设计与调试过程中遇到的问题及分析、体会在程序的最初调试中因为没有把握好各个函数之间的调用关系,因而出现了许多错误,比如得不到排序结果等,然后将所有排序的函数都写在了一个类中,这样,只要声明一次,以后就可以非常方便,准确的调用各个函数了。

所有排序的原理

所有排序的原理

所有排序的原理排序是将一组数据按照某种特定顺序进行排列的过程。

在计算机科学中,排序是一种基本的算法问题,涉及到许多常见的排序算法。

排序算法根据其基本原理和实现方式的不同,可以分为多种类型,如比较排序、非比较排序、稳定排序和非稳定排序等。

下面将详细介绍排序的原理和各种排序算法。

一、比较排序的原理比较排序是指通过比较数据之间的大小关系来确定数据的相对顺序。

所有常见的比较排序算法都基于这种原理,包括冒泡排序、插入排序、选择排序、归并排序、快速排序、堆排序等。

比较排序算法的时间复杂度一般为O(n^2)或O(nlogn),其中n是待排序元素的数量。

1. 冒泡排序原理冒泡排序是一种简单的比较排序算法,其基本思想是从待排序的元素中两两比较相邻元素的大小,并依次将较大的元素往后移,最终将最大的元素冒泡到序列的尾部。

重复这个过程,直到所有元素都有序。

2. 插入排序原理插入排序是一种简单直观的比较排序算法,其基本思想是将待排序序列分成已排序和未排序两部分,初始状态下已排序部分只包含第一个元素。

然后,依次将未排序部分的元素插入到已排序部分的正确位置,直到所有元素都有序。

3. 选择排序原理选择排序是一种简单直观的比较排序算法,其基本思想是每次从待排序的元素中选择最小(或最大)的元素,将其放到已排序部分的末尾。

重复这个过程,直到所有元素都有序。

4. 归并排序原理归并排序是一种典型的分治策略下的比较排序算法,其基本思想是将待排序的元素不断地二分,直到每个子序列只包含一个元素,然后将相邻的子序列两两归并,直到所有元素都有序。

5. 快速排序原理快速排序是一种常用的比较排序算法,其基本思想是通过一趟排序将待排序的元素分割成两部分,其中一部分的元素均比另一部分的元素小。

然后,对这两部分元素分别进行快速排序,最终将整个序列排序完成。

6. 堆排序原理堆排序是一种常用的比较排序算法,其基本思想是利用堆这种数据结构对待排序的元素进行排序。

内部排序算法的性能分析与探讨

内部排序算法的性能分析与探讨

表 ,采用不 同的测试组数 ,测试 了 6种 常用的 内部排序 算法的关键 字比较 次数 和移动 次数 ,从 时
间复杂度 方面给 出了 6种排序 算法的优劣. 关键 词 :算法评价 ;随机 乱序 ;内排序 ;比较次数 ;移动次数 中图分类号 :T 3 1 2 P 1. 1 5 文献标识码 :A 文章编号 :17 — 5 0 (0 1 5 00 — 7 6 2 0 2 2 1 )0 — 0 3 2
收 稿 日期 :2 1— 6 8 0 1 0 —1
作者简介 :申雪琴 (9 3 ) 17 一 ,女 ,甘肃张掖人 ,河西学院信 息技 术与传媒 学院讲 师 ,研 究方 向 :计算机软
件与理论.

5 ・ O
申雪琴 :内部排 序算法的性能分析 与探讨
动次数 的记 数操作.
21 可排序表 的抽 象数据类型 的定义 .
O 引 言
排序是数据 处理 中经 常使用 的一种运算 . 排序 的方 法很多 ,应 用也很广泛 . 排序 过程 中 ,文 在
件放在 内存 的称为 “ 内排 序” ;排序过程 中 ,不 仅需要 内存 ,还 需要外存 的称为 “ 排序 ”. 外 按所
用策略 的不 同 ,排序方法 又可 以分 为五种 :插入排 序 、选择排序 、交换排序 、分 配排序 和并归排
Ls m t ( / iE p )/ t y 若可排序表 为空表 ,则 返 回Tu ,否则返 回F l re ae s
● ● ● ● ● ●
】 D rea li A T O drbe s lt
上述定义 中 ,括号里面都各包含2 参数C ,还应包括返 回上述6 个 和S 种排序算 法的关键字 比较 次 数 和移动 次数 的 函数 . 别 为 :B b l o ) net r ) e c o ) u k o ) h l 分 u be r 、Isr ot( 、Sl t r 、Q i Sr 、S e — S t( S e S t( c t( l Sr ) epot( 其 功能依 次是 冒泡 排序 、插 入排序 、选择 排序 、快 速排序 、希尔排序 、堆 o t( 、H aSr ). 排序 ,返 回关键字 比较次数C 和移动次数S . 2 . 随机乱序 算法的 实现 2

数据结构之各种排序的实现与效率分析

数据结构之各种排序的实现与效率分析

各种排序的实现与效率分析一、排序原理(1)直接插入排序基本原理:这是最简单的一种排序方法,它的基本操作是将一个记录插入到已排好的有序表中,从而得到一个新的、记录增1的有序表。

效率分析:该排序算法简洁,易于实现。

从空间来看,他只需要一个记录的辅助空间,即空间复杂度为O(1).从时间来看,排序的基本操作为:比较两个关键字的大小和移动记录。

当待排序列中记录按关键字非递减有序排列(即正序)时,所需进行关键字间的比较次数达最小值n-1,记录不需移动;反之,当待排序列中记录按关键字非递增有序排列(即逆序)时,总的比较次数达最大值(n+2)(n-1)/2,记录移动也达到最大值(n+4)(n-2)/2.由于待排记录是随机的,可取最大值与最小值的平均值,约为n²/4.则直接插入排序的时间复杂度为O(n²).由此可知,直接插入排序的元素个数n越小越好,源序列排序度越高越好(正序时时间复杂度可提高至O(n))。

插入排序算法对于大数组,这种算法非常慢。

但是对于小数组,它比其他算法快。

其他算法因为待的数组元素很少,反而使得效率降低。

插入排序还有一个优点就是排序稳定。

(2)折半插入排序基本原理:折半插入是在直接插入排序的基础上实现的,不同的是折半插入排序在将数据插入一个有序表时,采用效率更高的“折半查找”来确定插入位置。

效率分析:由上可知该排序所需存储空间和直接插入排序相同。

从时间上比较,折半插入排序仅减少了关键字间的比较次数,为O(nlogn)。

而记录的移动次数不变。

因此,折半查找排序的时间复杂度为O(nlogn)+O(n²)= O(n²)。

排序稳定。

(3)希尔排序基本原理:希尔排序也一种插入排序类的方法,由于直接插入排序序列越短越好,源序列的排序度越好效率越高。

Shell 根据这两点分析结果进行了改进,将待排记录序列以一定的增量间隔dk 分割成多个子序列,对每个子序列分别进行一趟直接插入排序, 然后逐步减小分组的步长dk,对于每一个步长dk 下的各个子序列进行同样方法的排序,直到步长为1 时再进行一次整体排序。

排序算法分析和比较

排序算法分析和比较

一、设计思想排序是数据处理中使用频率很高的一种操作,是数据查询之前需要进行的一项基础操作。

它是将任意序列的数据元素(或记录)按关键字有序(升序或降序)重新排列的过程。

排序的过程中有两种基本操作:一是比较两个关键字的值;二是根据比较结果移动记录位置。

排序的算法有很多种,这里仅对插入排序、选择排序、希尔排序、归并排序和快速排序作了比较。

直接插入排序算法基本思路:直接插入排序时将一个元素插入已排好的有序数组中,从而得到一个元素个数增加1的新的有序数组。

其具体实现过程是,将第i个元素与已经排好序的i-1个元素依次进行比较,再将所有大于第i个元素的元素后移一个位置,直到遇到小于或等于第i个元素,此时该元素的后面一个位置为空,将i元素插入此空位即可。

选择排序算法基本思路:定义两个数组sela[]和temp[],sela[]用来存放待排序数组,temp[]用来存放排好序的数组。

第一趟,将sela[]数组中n个元素进行比较,找出其中最小的元素放入temp[]的第一个位置,同时将sela[]中将该元素位置设置为无穷大。

第二趟,将sela[]数组中n个元素进行比较,找出其中最小的元素放入temp[]的第二个位置,同时将sela[]中将该元素位置设置为无穷大。

以此类推,n趟后将sela[]中所有元素都已排好序放入temp[]数组中。

希尔排序算法基本思路:希尔排序又称为变长步径排序,它也是一种基于插入排序的思想。

其基本思路是,定义一个步长数组gaps[1,5,13,43……],先选取合适的大步长gap将整个待排序的元素按步长gap分成若干子序列,第一个子序列的元素为a[0]、a[0+gap]、a[0+2gap]……a[0+k*gap];第二列为a[1]、a[1+gap]、a[1+2gap]……a[1+k*gap];……。

然后,对这些子序列分别进行插入排序,然后将gap按gaps[]数组中的步长缩小,按缩小后的步长再进行子序列划分排序,再减小步长直到步长为1为止。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四:内部排序算法的实现与比较
一、问题描述
1.实验题目:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大致执行时间。

试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。

2.基本要求:(1)对常用的内部排序算法进行比较:直接插入排序、简单选择排序、冒泡排序、快速排序、希尔排序、归并排序。

(2利用随机函数产生N(N=30000)个随机整数,作为输入数据作比较;比较的指标为关键字参加的比较次数和关键字的移动次数(关键字交换记为3次移动)。

(3)对结果作出简要分析。

3.测试数据:随机函数产生。

二、需求分析
1.程序所能达到的基本可能:通过随机数据产生N个随机数,作为输入数据作比较;对常用的内部排序算法:直接插入排序、简单选择排序、冒泡排序、快速排序、希尔排序、归并排序进行比较:比较的指标为关键字参加的比较次数和关键字的移动次数(关键字交换记为3次移动)。

最后结果输出各种排序算法的关键字参加的比较次数和关键字的移动次数,并按从小到大排列。

2.输入的形式及输入值范围:随机函数产生的N(N=30000)个随机整数。

3.输出的形式:输出各种排序算法的关键字参加的比较次数和关键字的移动次数。

并按从小到大排列。

4.测试数据要求:随机函数产生的N(N=30000)个随机整数。

三、概要设计
1. 所用到得数据结构及其ADT
为了实现上述功能,应以一维数组表示集合数据类型。

int s[N];
int compare[6]={0},move[6]={0},D[N]={0},RS[N]={0};
基本操作:
数组赋值:
for(i=1;i<N;i++)
{
s[i]=rand()%100;
printf("%d\t",s[i]);
}
void copys(int S[],int RS[],int n)
实现每个操作的伪码,重点语句加注释
1)void copys(int S[],int RS[],int n)择法 ,2.冒泡法 ,3.插入法 ,4.快速法 , 5.希尔排序法 ,6.归并排序法,7.输出比较信息,8.退出\n");
scanf(" %d",&j);
switch(j)
{
case 1:
SelectSort(RS,N-1);
break;
case 2:
BubbleSort(RS,N-1);
break;
case 3:
InsertSort(RS,N-1);
break;
case 4:
QuickSortprint(RS,N-1);
break;
case 5:
Shellsort(RS,N-1);
break;
case 6:
MSort(RS,1,N-1);
printf("归并排序后的结果:");
for(i=1;i<N;i++)
printf("%d\t",D[i]);
printf("\n");
printf("关键字参加的比较次数:%d,关键字的移动次数:%d\n",compare[5],move[5]);
printf("\n");
break;
case 7:
SelectSort(compare,5);
SelectSort(move,5);
printf("关键字参加的比较次数:\n");
for(i=1;i<=5;i++)
printf("%d\t",compare[i]);
printf("\n");
printf("关键字的移动次数:\n");
for(i=1;i<=5;i++)
printf("%d\t",move[i]);
printf("\n");
break;
case 8:
printf("Current local time and date:%s",asctime(timeinfo));
exit(0);
break;
}
}while(1);
}
五、调试分析
1. 设计与调试过程中遇到的问题分析、体会
调试过程:由于本次程序设计的数据和模块比较多,所以采用分块调试的方法,在编写完一个内部排序算法后,为了验证是否排序成功以及所输出的关键字比较次数和移动次数是否正确,采用先定义一个需要排序9个数字的数组,S[10]={0,1,2,3,4,5,6,7,8,9}和S[10]={0,9,8,7,6,5,4,3,2,1},用这两个数组检验程序的正确性与否。

调试步骤,程序及相关结果如下:
1)直接选择排序:
#include <>
#include <>
#include <>
void SelectSort(int RS[],int n)
择法 ,2.
冒泡法 ,3.插入法 ,4.快速法 , 5.希尔排序法 ,6.归并排序法,7.输出比较信息,8.退出\n");
scanf(" %d",&j);
switch(j)
{
case 1:
SelectSort(RS,N-1);
break;
case 2:
BubbleSort(RS,N-1);
break;
case 3:
InsertSort(RS,N-1);
break;
case 4:
QuickSortprint(RS,N-1);
break;
case 5:
Shellsort(RS,N-1);
break;
case 6:
MSort(RS,1,N-1);
printf("归并排序后的结果:");
for(i=1;i<N;i++)
printf("%d\t",D[i]);
printf("\n");
printf("关键字参加的比较次数:%d,关键字的移动次数:%d\n",compare[5],move[5]);
printf("\n");
break;
case 7:
SelectSort(compare,5);
SelectSort(move,5);
printf("关键字参加的比较次数:\n");
for(i=1;i<=5;i++)
printf("%d\t",compare[i]);
printf("\n");
printf("关键字的移动次数:\n");
for(i=1;i<=5;i++)
printf("%d\t",move[i]);
printf("\n");
break;
case 8:
printf("Current local time and date:%s",asctime(timeinfo));
exit(0);
break;
}
}while(1);
]
九、实验收获和感想。

相关文档
最新文档