“排序”就是按照某个关键字的大小,将若干对象从小到大或者从大到小进行重新排列。关键字是对象的某一个属性,它可以是任何基本数据类型,甚至结构体等。
例如,体育课上我们会按照身高从矮到高站队,这就是“升序”排序,身高是我们每个人的一个属性,也就是排序的关键字。
排序算法非常多,其中最基本的有选择排序、冒泡排序和插入排序三种。其本质上都是通过数组中的元素比较和交换来实现的,关键是数组下标的分析。
例1:
【问题描述】
给出n个同学的身高,请根据他们的身高升序排列并输出排序结果。
【输入格式】
第一行1个正整数n,表示有n个同学的身高,2<n≤100。
第二行包含n个正整数,之间用一个空格隔开,表示n个同学的身高。每个同学的身高都在150~200厘米之间。
【输出格式】
一行n个正整数,之间用一个空格隔开,表示n个同学根据身高升序排列的结果。
【输入样例】
7
180 170 176 160 155 150 160
【输出样例】
150 155 160 160 170 176 180
一、选择排序
选择排序的基本思想是:每一趟从待排序的数据中,通过“打擂台”比较选出最小元素,放在这些数据的最前面。这样,第一趟把n个数中(第1个到第n个)最小的放在第一个位置,第二趟把剩余的n-1个数中(第2个到第n个)最小的放在第二个位置,第三趟把剩余的n-2个数中(第3个到第n个)最小的放在第三个位,……第n-1趟把剩下的2个数中(第n-1个到第n个)最小的放在第n-1个位置,剩下的最后一个数(第n个)一定最大,自然落在了第n个位置。
//例1 选择排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++)
if(a[i]>a[j])
swap(a[i],a[j]);
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
处理逻辑:
二、冒泡排序
冒泡排序的基本思想是:从第一个数开始,依次不断比较相邻的两个元素,如果“逆序”就交换。这样,一趟排序结束后,最大的元素就放在了第n个位置了。对于样例数据,第一趟冒泡排序的过程如下:
用同样的方法,第二趟把剩余的前n-1个数中最大的交换到第n-1个位置,第三趟把剩余的前n-2个数中最大的交换到第n-2个位置,……经过n-1趟,排序结束。
//例1 冒泡排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<n;i++){
for(int j=1;j<=n-i;j++){
if(a[j]>a[j+1])
swap(a[j],a[j+1]);
}
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
对于冒泡排序,我们还可以做些算法“优化”。如果一趟排序下来,都没有任何“逆序”数对,即没有发生“交换”操作,则说明已经排好序了。此时,就可以立刻退出循环。
三、插入排序
插入排序的基本思想是:把所有待排序元素分成前后两段,前一段是已经排好序的,后一段是待排序的。每一趟都是把后一段的第一个数“插入”到前一段的某一个位置,保证前一段仍然是有序的。开始时,第1个数作为前一段肯定是有序的;第一趟,把第2个数插入进去,保证前2个数有序;第二趟,把第3个数插入进去,保证前3个数有;……第n-1趟,把第n个数插入进去,保证n个数都有序。
//例1 插入排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n,t,k;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=2;i<=n;i++){
t=a[i];
k=1;
while(a[k]<=t && k<i)
k++;
for(int j=i-1;j>=k;j--)
a[j+1]=a[j];
a[k]=t;
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
四、计数排序
计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。
//例1 计数排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],x[50],n,maxx=-1e9,minn=1e9;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];
a[x[i]]++;
if(x[i]>maxx) maxx=x[i];
if(x[i]<minn) minn=x[i];
}
for(int i=minn;i<=maxx;i++){
for(int j=1;j<=a[i];j++)
cout<<i<<" ";
}
return 0;
}
下面是各自动画演示:
1、选择排序
2、冒泡排序
3、插入排序
四、计数排序