9.21 算法排序之冒泡排序
参考资料:
拉勾的算法视频:https://www.bilibili.com/video/BV1DT4y1G7ha?p=5
-
冒泡排序
-
定义:
-
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,依次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(大的先确定)。
-
-
算法实现
-
比较相邻的元素。如果数组第一个比第二个大,就交换它们两个位置(大的排在末端);
-
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
-
针对所有的元素重复以上的步骤,除了最后一个;
-
重复步骤,直到排序完成。
-
代码实现
- 根据算法思想的代码
-
int[] array = {14,66,27,1,2,4,78,67,8999,123,56}; if(array == null || array.length <= 1){ return; } int length = array.length; //外层控制比较轮数 for ( int i = 0; i < length - 1; i++) { //内层控制比较的轮数,大的往前交换 //(array.length - 1)防止索引越界,(array.length - 1 - i)减少比较次数 for (int j = 0 ;j < length - 1 - i ;j++ ){ //// 前面的数大于后面的数就进行交换 if(array[j] > array[j+1]){ int temp = array[j+1]; array[j+1] = array[j]; array[j] = temp; } } System.out.println(Arrays.toString(array));
-
- 优化冒泡排序
- 目前主要的优化手段就是加变量看是否发生置换
-
//装载临时变量 int temp; //记录是否发生了置换, 0 表示没有发生置换、 1 表示发生了置换 int isChange; //外层循环是排序的趟数 for (int i = 0; i < array.length - 1; i++) { //每比较一趟就重新初始化为0 isChange = 0; //内层循环是当前趟数需要比较的次数 for (int j = 0; j < array.length - i - 1; j++) { //前一位与后一位与前一位比较,如果前一位比后一位要大,那么交换 if (array[j] > array[j + 1]) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; //如果进到这里面了,说明发生置换了 isChange = 1; } } //如果比较完一趟没有发生置换,那么说明已经排好序了,不需要再执行下去了 if (isChange == 0) { break; } }
-
- 第二种优化手段就是把上面0,1可以改成布尔变量控制,原理是一样的
-
//设置变量看有没有交换 boolean hasChange = true; for (int i = 0;i < array.length -1 && hasChange; i++){ hasChange = false; for (int j = 0;j < array.length - 1 - i ; j++){ if(array[j]>array[j+1]){ int temp = array[j+1]; array[j + 1 ] = array[j]; array[j] = temp; hasChange = true; } } }
-
- 目前主要的优化手段就是加变量看是否发生置换
- 根据算法思想的代码
-
算法分析
-
数组是n,空间复杂读是O(1)
-
最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2)是N的平方 平均情况:T(n) = O(n2)
- 冒泡排序是稳定的:主要原因是:俩俩比较的时候,没有对相等的数据进行交换(因为没必要)。因此它不存在2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序不相同。
- 判断某排序算法是否稳定,我们可以简单理解成:排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同
- 2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序不相同,因此,我们就说它是不稳定的
- 稳定性的意义:很清晰的指出,只有当在“二次”排序时不想破坏原先次序,稳定性才有意义
努力不一定成功,但不努力一定会失败~