原始冒泡排序实现
#include<stdio.h> int main(void){ //定义数组大小 int N=8; //用于计算交换的次数 int sum=0; //定义数组元素 int array[]={5,8,6,3,9,2,1,7}; //使用冒泡的方式进行排序 for(int i=0;i<N;i++){ for(int j=0;j+i<N-1;j++){ if(array[j]>array[j+1]){ int temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; } } sum++; } //输出 for(i=0;i<N;i++){ printf("%d ",array[i]); } printf("\n"); printf("大循环的次数为:%d",sum); printf("\n"); return 0; }
优化一
- 如果在原始冒泡排序的后边几轮已经不需要排序了,但是按照原先的排序算法,还是要进行执行,针对这种情况进行改进,增加一个判断的变量 isSorted = true,如果这有元素发生交换,那么会将 isSorted 变为 false,否则的话表示已经排序好了不需要进行后边的交换了,那么直接 break
#include<stdio.h> int main(void){ //定义数组大小 int N=8; //用于计算交换的次数 int sum=0; //定义数组元素 int array[]={5,8,6,3,9,2,1,7}; //使用冒泡的方式进行排序 for(int i=0;i<N;i++){ //有序标记,每一轮的初始值都是true bool isSorted=true; for(int j=0;j+i<N-1;j++){ if(array[j]>array[j+1]){ int temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; //因为有元素交换,索引数组还不是有序的,标记变为false isSorted=false; } } if(isSorted){ break; } sum++; } //输出 for(i=0;i<N;i++){ printf("%d ",array[i]); } printf("\n"); printf("交换的次数为:%d",sum); printf("\n"); return 0; }
优化二
- 如果在某次交换中还没有交换到边界,但是后边的数据已经是有序的了,这种情况我们可以进行优化
#include<stdio.h> int main(void){ //定义数组大小 int N=8; //用于计算交换的次数 int sum=0; //定义数组元素 int array[]={2,1,3,4,5,6,7,8}; //使用冒泡的方式进行排序 for(int i=0;i<N;i++){ //有序标记,每一轮的初始值都是true bool isSorted=true; //下次要进行交换的边界 int sortBorder=N-1; for(int j=0;j+i<sortBorder;j++){ if(array[j]>array[j+1]){ int temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; //因为有元素交换,索引数组还不是有序的,标记变为false isSorted=false; //确定边界 sortBorder=j; } } if(isSorted){ break; } sum++; } //输出 for(i=0;i<N;i++){ printf("%d ",array[i]); } printf("\n"); printf("大循环次数为:%d",sum); printf("\n"); return 0; }
鸡尾酒排序
- 鸡尾酒排序的元素比较和交换过程是双向的
- 大致思想:奇数轮,从左向右比较和交换,偶数轮,从右向左比较和交换
#include<stdio.h> int main(void){ //定义数组大小 int N=8; //用于计算交换的次数 int sum=0; //定义数组元素 int array[]={2,3,4,5,6,7,8,1}; //使用冒泡的方式进行排序 for(int i=0;i<N/2;i++){ //有序标记,每一轮的初始值都是true bool isSorted=true; //奇数轮,从左向右比较和交换 for(int j=i;j<N-i-1;j++){ //交换 if(array[j]>array[j+1]){ int t1=array[j]; array[j]=array[j+1]; array[j+1]=t1; //因为有元素交换,索引数组还不是有序的,标记变为false isSorted=false; } } if(isSorted){ break; } //在偶数轮之前,将isSorted重新标记为true isSorted=true; for(j=N-i-1;j>i;j--){ //交换 if(array[j]<array[j-1]){ int t2=array[j]; array[j]=array[j-1]; array[j-1]=t2; //因为有元素交换,索引数组还不是有序的,标记变为false isSorted=false; } } if(isSorted){ break; } sum++; } //输出 for(i=0;i<N;i++){ printf("%d ",array[i]); } printf("\n"); printf("大循环次数为:%d",sum); printf("\n"); return 0; }