冒泡排序
冒泡排序属于交换排序的一种,算法如其名,它通过两两比较相邻关键字,如有逆序则交换,不断使关键字小的往上冒,关键字大的往下沉。
冒泡排序这里给出两种,其中一种容易和选择排序混淆,在后面也给了区分解析。
void simplebubble(int a[],int len){ //一种比较暴力效率较低的冒泡
int i,j;
for(i=0;i<len;i++){ //这里两步和后文选择排序容易混淆
for(j=0;j<len-i;j++){
if(a[j]>a[j+1]){
int temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
}
经过改良的冒泡排序,减少了在已顺序的情况下很多多余的操作
void bubblesort(int a[],int len){
int flag=1,i; //设置flag是为了当不在发生交换时表示已经排序完成,减少不必要的操作 ,使排序更加高效
while((len>0)&&(flag=1)){
flag=0;
for(i=0;i<len;i++){
if(a[i]>a[i+1]){
flag=1;
int temp=a[i]; //交换操作
a[i]=a[i+1];
a[i+1]=temp;
}
}
len--;
}
}
选择排序
void select(int a[],int len){
int i,j;
for(i=0;i<len;i++){
int min=i;
for(j=i+1;j<=len;j++){
if(a[j]<a[min]) min=j; //每一轮记录下当前最小的那个下标
}
if(min!=i){ //把当前最小的放在已经选择排序好的序列尾
int temp=a[i];
a[i]=a[min];
a[min]=temp;
}
}
}
区别解析
第一种冒泡排序和选择排序在写法上很相近,我觉得这可能使很多人混淆的点吧。先说本质原理上的不同,冒泡排序是不断比较两个值,出现逆序就交换,选择排序是每一轮选择当前未排序序列最小放到已排好序的序列末尾。再说形式上的不同,冒泡在双重循环中都是从下标从0开始,选择排序内层for循环则是从i+1开始(他们内在逻辑就要求这样写)。选择排序要记录下下标,冒泡排序不用。
主函数测试
int main(){
int i;
int a[]={1,10,5,6,9};
simplebubble(a,5);
// bubblesort(a,5);
// select(a,5);
for(i=0;i<5;i++) printf("%d ",a[i]);
}
知识补充
冒泡排序和选择排序时间复杂度都是o(n2),他们两种都是稳定排序,顺序和链式都可用。
希望本篇博客可以给疑惑的同学提供一些帮助。