排序是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作;排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面,一个优秀的算法可以节省大量的资源。
一、选择排序
选择排序算法的基本思想是:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
例1、生成20个0到100之间的随机数,用选择排序法从小到大排序后再次输出。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101];
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
for (int i=1;i<=rs-1;i++)
for (int j=i+1;j<=rs;j++)
if (fs[i]>fs[j]) swap(fs[i],fs[j]);
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
算法优化:
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101],t;
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
for (int i=1;i<=rs-1;i++) {
t=i;
for (int j=i+1;j<=rs;j++)
if (fs[t]>fs[j]) t=j;
if (t!=i) swap(fs[i],fs[t]);
}
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
二、冒泡排序
冒泡排序算法的基本思想是:将待排序的数据序列看作竖直排列的一串“气泡”,值较小的数据比较轻,因此要往上浮。在冒泡排序算法中,我们要对这个“气泡”序列处理若干遍。所谓处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的记录的顺序是否正确。如果发现两个相邻记录的顺序不对,即“轻”的记录在下面,就交换他们的位置。显然,处理一遍之后,“最轻”的记录就浮到了最高位置。处理两遍之后,“次轻”的记录就浮到了次高位置。在作第二遍处理时,由于最高位置上的记录是“最轻”记录,所以不必检查。一般地,第i遍处理时,不必检查第i-1高位置的记录,因为经过前面i-1遍的处理,它们已经正确地排好序了。冒泡排序是一种稳定的排序方法。
例2、生成20个0到100之间的随机数,用冒泡排序法从小到大排序后再次输出。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101];
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
for (int i=1;i<=rs-1;i++)
for (int j=1;j<=rs-i;j++)
if (fs[j]>fs[j+1]) swap(fs[j],fs[j+1]);
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
三、插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法。插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
例3、生成20个0到100之间的随机数,用插入排序法从小到大排序后再次输出。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101],t;
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
for (int i=2;i<=rs;i++) {
fs[0]=fs[i];t=i-1;
while (fs[0]<fs[t]) fs[t+1]=fs[t],t--;
fs[t+1]=fs[0];
}
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
四、快速排序
快速排序是对冒泡排序的一种改进,几乎是目前所有排序法中速度最快的方法。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
例4、生成20个0到100之间的随机数,用快速排序法从小到大排序后再次输出。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101];
void qs(int l,int r) {
int i,j,m;
i=l;j=r;
m=fs[(i+j)/2];
while (i<=j) {
while (fs[i]<m) i++;
while (fs[j]>m) j--;
if (i<=j) swap(fs[i],fs[j]),i++,j--;
}
if (l<j) qs(l,j);
if (i<r) qs(i,r);
}
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
qs(1,rs);
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
五、归并排序
归并排序是一种基于比较的排序算法,它的基本思想是分治,即“分而治之”。归并算法将给定的包含n个元素的数组分而两个数组,每个数组包含n/2个元素;接着对两个数组分别执行归并排序,直至数组只剩一个元素,不能再分割;最后通过merge操作将两个已排序的数组进行合并,完成排序。归并排序的算法是稳定的。
例5、生成20个0到100之间的随机数,用归并排序法从小到大排序后再次输出。
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int rs=20; //确定人数
int fs[101],sc[101],t;
void mergesort(int s,int e) {
if (s==e) return; //若区间只有1个数就不用排了
int m=(s+e)/2; //取区间的中点
mergesort(s,m); //对左边子区间进行排序
mergesort(m+1,e); //对右边子区间进行排序
int i,j,k;
i=s;j=m+1;k=s;
while (i<=m && j<=e) {
if (fs[i]<=fs[j]) sc[k]=fs[i],i++;
else sc[k]=fs[j],j++;
k++;
}
while (i<=m) sc[k]=fs[i],i++,k++;
while (j<=e) sc[k]=fs[j],j++,k++;
for (int i=s;i<=e;i++) fs[i]=sc[i];
}
int main() {
srand(time(0));
for (int i=1;i<=rs;i++) fs[i]=rand()%101;
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
cout<<endl;
mergesort(1,rs);
for (int i=1;i<=rs;i++) cout<<fs[i]<<' ';
return 0;
}
附:计算程序用时
#include<iostream>
#include<ctime>
using namespace std;
double s,e,ys;
int main() {
s=clock();
...
程序代码
...
e=clock();
ys=((double)(e-s)/CLK_TCK);
cout<<ys; //输出程序用时
return 0;
}