八大排序——冒泡排序的优化算法及性能分析(C语言)

冒泡排序(Bubble Sort)

1、冒泡排序的思想:它重复地走访需要排序的数列,按照已经规定好的排序顺序,每一次比较相邻两个元素,如果他们的顺序错误就把他们交换过来。 直到没有再需要交换的元素,该数列就排序完成。

2、冒泡排序的算法运作(由小到大的排列顺序):

有一个数组a[10],用变量i表示它的下标(i从0开始)——

  1. 比较两个相邻元素a[i]和a[i+1],如果a[i]>a[i+1],就交换这两个数的位置;
  2. 重复执行第一步,直到比较到最后一对的时候(例:首次是a[8]和a[9],此 时,a[9]的值为该数组的最大值,这个值属于有序数列);
  3. 对所有元素(除了有序数列里的元素),重复执行第一步和第二步,每执行完一次,都会找到当前比较的数里最大的那个(有序数列就会增加一个);
  4. 随着参与比较的元素越来越少,最终没有任何一对元素需要比较的时候,排序完成。

 

3、传统的冒泡排序图示:

 

 

传统的冒泡排序的代码:

int a[8]={3,2,5,8,4,7,6,9};

for(int i=0;i<8;i++)//外层循环:要比较的次数;

{

for(int j=0;j<7-i;j++)内层循环:每次比较时,要比较的元素的范围;(这里就相当于j<n-i-1 )

{

if(a[j]>a[j+1])交换的三条语句

{

int temp=a[j];

a[j]=a[j+1];

a[j+1]=temp;

}

}

}

4、优化1——定义一个flag,用来判断有没有进行交换,如果在某次内层循环中没有交换操作,就说明此时数组已经是有序了的,不用再进行判断,这样可以节省时间。

int flag=1;

for(int i=0;i<8&&flag;i++){

flag=0;

for(int j=0;j<7-i;j++){

if(a[j]>a[j+1]){

int temp=a[j];

a[j]=a[j+1];

a[j+1]=temp;

flag=1;

}

}

}

5、优化2——每一次交换记录最后一次交换的位置,为零的时候就停止。

int i= 8 -1; //初始时,最后位置保持不变,相当于a.length-1

while ( i ) {

int pos= 0; //每趟开始时,无记录交换

for (int j= 0; j< i; j++)

if (a[j]> a[j+1]) {

pos= j; //记录交换的位置

int temp = a[j];

a[j]=a[j+1];

a[j+1]=temp;

}

i= pos; //为下一趟排序作准备

}

 

6、优化3——鸡尾酒排序(Cocktail Sort)(又名:双向冒泡排序 (Bidirectional Bubble Sort)、波浪排序 (Ripple Sort)、摇曳排序 (Shuffle Sort)、飞梭排序 (Shuttle Sort) 和欢乐时光排序 (Happy Hour Sort)

原理:此算法以双向进行排序,鸡尾酒排序等于是冒泡排序的轻微变形

和传统冒泡的比较:不同的地方在于从低到高然后从高到低,而冒泡排序每次都是从低到高去比较序列里的每个元素。可以得到比冒泡排序稍微好一点的效能,原因是冒泡排序只能从一个方向进行比对,每次循环只移动一个项目

 

图解:


代码:


public void cocktail_sort(int[] a){

int left = 0, right = a.length-1;

int temp;
while(left<right){

for(int i=left;i<right;i++){ //找到当前排序元素里最大的那个,放在右侧

if(arr[i]>a[i+1]){

temp = a[i];

arr[i] = a[i+1] ;

a[i+1] = temp;

}

}

right--;

for(int j=right;j>left;j--){//找到当前排序元素里最小的那个,放在左侧
if(a[j-1]>a[j]){

temp = a[j];

a[i] = a[j+1] ;

a[j+1] = temp;}
}

left++;		



}

}

 

7、性能分析:

时间复杂度:冒泡排序在平均和最坏情况下的时间复杂度都是O(n^2),最好情况下都是O(n);

空间复杂度:O(1);

稳定性:冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不必再去交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

  • 56
    点赞
  • 175
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
冒泡排序是一种简单的排序算法,它重复地遍历待排序的元素,比较相邻元素的大小,如果顺序错误就交换它们,直到没有需要交换的元素为止。下面是冒泡排序C语言实现: ```c void bubbleSort(int arr[], int n) { for(int i = 0; i < n-1; i++) { int flag = 0; //是否冒泡 for(int j = 0; j < n-1; j++) { if(arr[j > arr[j+1]) { swap(&arr[j], &arr[j+1]); flag = 1; } } if(flag == 0) { //如果没有发生交换,说明数组已经有序,可以提前结束循环 break; } } } ``` 在这个实现中,冒泡排序函数`bubbleSort`接受一个整型数组`arr`和数组长度`n`作为参数。它使用两层循环来遍历数组,并通过比较相邻元素的大小来进行交换。内层循环每次将最大的元素冒泡到数组的末尾。外层循环控制了冒泡的轮数,每一轮都会将当前未排序的最大元素放在正确的位置上。如果在某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环,从而提高算法的效率。 需要注意的是,上述代码中使用了一个`swap`函数来交换两个元素的值,你可以根据需要自行实现该函数。此外,为了减少冒泡排序的时间复杂度,可以在内层循环中添加一个标志位`flag`,用于标记是否发生了交换。如果某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环。这样可以避免不必要的比较和交换操作,提高排序的效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值