扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
上篇文章【数据结构与算法——C语言版】4. 排序算法(1)——选择排序我们介绍了排序算法中的选择排序,其时间复杂度是O(n2),本篇文章我们将介绍另一种同样时间复杂度是O(n2)的排序算法——冒牌排序,这两种算法思路不同,但都是两层循环,实用性不高,但有必要通过讲解来掌握不同的算法思路。
创新互联公司是一家集网站建设,乐山企业网站建设,乐山品牌网站建设,网站定制,乐山网站建设报价,网络营销,网络优化,乐山网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。冒泡排序核心思想选择排序的核心思想是每次找到最小值并与第i个元素交换,找n次。
而冒泡排序的核心思想是每次遍历整个数组,比较相邻的两个元素arr[i]和arr[j],将较大者放在arr[j]的位置,然后继续比较arr[j]和arr[j+1];将数组遍历n次后(n为数组元素个数),数组升序有序。
该算法能使数组有序的核心原因如下:
从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中大的一个或最小的一个。这个数就会从序列的最右边冒出来。
以从小到大排序为例,第一轮比较后,所有数中大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
用一张图片直观的观察一下:
第一轮遍历中,总是选择大的那个数并交换至靠右的位置,第一轮比较完成后,数组中大的元素50就被“冒”到了右边
最后一轮遍历,arr[0]就是最小的元素2,所以最后一轮遍历没有发生交换,即数组已升序有序。
我们还是用一个例子,一步步带着大家来理解冒泡排序的过程。
数组
arr[5] = {5,1,4,2,8}
,如果采用冒泡排序对其进行升序(由小到大)排序,则整个排序过程如下所示:
第一次遍历数组arr,两两比较arr[i]和arr[i+1]
,并将较大者交换到arr[i+1]
。第一次遍历前,数组arr[5] = {5,1,4,2,8}
;遍历后,数组arr[5] = {1,4,2,5,8}
;此时arr[4]已经是大值8,所以下次遍历我们只需要遍历arr[0 ~ 3]
第二次遍历数组arr,两两比较arr[i]和arr[i+1]
,并将较大者交换到arr[i+1]
。第一次遍历前,数组arr[5] = {1,4,2,5,8}
;遍历后,数组arr[5] = {1,2,4,5,8}
;此时arr[3]已经是次大值5,且arr[3~4]保持升序有序;所以下次遍历我们只需要遍历arr[0 ~ 2];
第三次遍历数组arr,两两比较arr[i]和arr[i+1]
,并将较大者交换到arr[i+1]
。第一次遍历前,数组arr[5] = {1,2,4,5,8}
;遍历后,数组arr[5] = {1,2,4,5,8}
4. 第四次遍历数组arr,两两比较arr[i]和arr[i+1]
,并将较大者交换到arr[i+1]
。第一次遍历前,数组arr[5] = {1,2,4,5,8}
;遍历后,数组arr[5] = {1,2,4,5,8}
5. 第五次遍历数组arr,这次我们只需要遍历 arr[0~0];也就是只剩下一个元素arr[0];所以无需比较,产生的数组已经升序有序
void bubbleSort(int arr[], int size)
{for (int i = 0; i< size; i++) // 可优化点1
{int count = 0;
for (int j = 0; j< size - i; j++) // 每次遍历都会产生一个较大值放到后面,所以第i遍历就只需要比较size - i个元素
{ if (arr[j] >arr[j+1])//这是升序排法,前一个数和后一个数比较,如果前数大则与后一个数换位置
{ int tem = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tem;
count = 1;
}
}
if (count == 0) {// 优化点2:如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
}
注释的位置指出了两个优化点
第一个优化点,我们可以修改为for (int i = 0; i< size - 1; i++)
通过上面的图描述,也可以看出实际上n个元素的数组,我们只需要遍历n-1次,第n次遍历时数组只剩下第一个元素“需要”比较,只有一个元素所以可省去多出来的一次循环
第二个优化点,其实已经写出来了,每次遍历比较前,用count记录交换的次数,如果某趟没有发生交换,说明此时数组已经有序,可以直接退出循环
其中,第一个优化点不建议,因为优化跟没优化是一样的,写上size - 1反倒会造成一些误导(因为数组遍历一般都是[0~size))
第二个优化点可以加上,如果待排序数组是{1,2,3,5,4}
,这样我们只需要执行一次遍历,节省了很多时间
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流