在面试的时候我们经常会被问到排序,比如有插入排序,冒泡排序等等,我们今天就讲下冒泡排序以及优化。
一想到冒泡排序马上就会想起使用双循环来实现:
先定义一个数组 int[] array = {3,4,2,1,5,7,6};
然后定义方法
public static void sort1(int[] array){
int temp;
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
System.out.println(Arrays.toString(array));
}
}
这样就是我们最常见的冒泡排序,但是通过每次排完需,我们会发现有点问题,比如上面这个方法的执行过程:
[3, 2, 1, 4, 5, 6, 7]
[2, 1, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
我们会发现从第4次开始,后面每次打印的都是一样的结果,这显然效率不高,既然这样,那肯定可以优化的。
我们先观察下排序后的结果,第一次排序后的结果是:
[3, 2, 1, 4, 5, 6, 7]
在排序的过程中,第j 都会和第j+1位做比较,这其实是可以不用这样的,
我们可以加个标记,也就是在第一个for循环中加个标记,标记当前是否是有序数组,若是,则跳出循环;
我们在定义一个方法,对刚才的排序进行优化:
public static void Optimize1(int array[]){
int temp=0;
for(int i=0;i<array.length;i++){
//有序标记,每一轮的初始是true
boolean isSorted = true;
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;
//有元素交换,所以不是有序,标记为false
isSorted = false;
}
}
if(isSorted){
break;
}
System.out.println(Arrays.toString(array));
}
}
排序的执行过程如下:
[3, 2, 1, 4, 5, 6, 7]
[2, 1, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
只执行了三次就排好了,这比第一种方法效率要高;
但是这还不是最高效的,我们再观察下,发现第一次排完序后
[3, 2, 1, 4, 5, 6, 7]
4,5,6,7 已经是一个有序数列了,那可不可以这样,每次排完序后,标记最后一次排序的位置,下次再对比的时候,只要对比到上次
最后的一个位置即可,因为上次排完序后的最后一个位置开始,到数组完,一定是一个有序数列。
所以冒泡排序最优版如下:
public static void sort(int array[]){
int temp =0;
//记录每次最后一次交换的位置
int lastExchangeIndex =0;
//无序数列边界,每次比较只需比到这里为止
int sortBorder = array.length-1;
for(int i=0;i<array.length;i++){
//有序标记,每一轮的初始是true
boolean isSorted = true;
for(int j=0;j<sortBorder;j++){
if(array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
//有元素交换,所以不是有序,标记为false
isSorted = false;
//把无序数列的边界更新为最后一次元素交换的位置
lastExchangeIndex = j;
}
}
//更新无序数列边界
sortBorder = lastExchangeIndex;
if(isSorted){
break;
}
System.out.println(Arrays.toString(array));
}
}
分享到:
相关推荐
### 冒泡排序优化算法 #### 一、冒泡排序简介与原理 冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复进行的,直到没有再...
为了优化冒泡排序,我们可以引入两个关键策略:设置标志位和添加提前结束条件。 1. 设置标志位:在每一轮遍历结束后,如果没有发生过交换,说明序列已经有序,可以提前结束排序。我们可以在外层循环中添加一个布尔...
冒泡排序是一种基础且历史悠久的排序算法,它通过重复遍历待排序的...优化后的冒泡排序可以提高效率,而二分查找则是在有序数据集中的高效查找工具。通过这些基础知识的学习,开发者可以更好地理解和应用更复杂的算法。
对于教学非常的方便使用,在原来普通算法的基础上做一个优化,可以节省很多的时间
### 基于C语言的优化冒泡排序核心代码解析 #### 一、冒泡排序简介 冒泡排序是一种简单的排序算法,它重复地遍历要排序的元素列,依次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。遍历元素的工作是...
总结来说,S7-200SMART PLC实现冒泡排序优化版的关键在于利用ST语言的强大功能,结合条件判断和数据类型的动态处理,实现排序方式和数据类型的多样化。通过这种方式,我们可以创建出既高效又灵活的PLC排序程序,服务...
③ 掌握几种常见的冒泡排序优化策略,提升算法性能;④ 通过实际应用实例加深对冒泡排序的理解和应用。 阅读建议:在阅读过程中,建议边读边实践代码,通过调试和优化来深刻理解冒泡排序的工作机制。此外,结合其他...
博客文章"优化冒泡排序和选择排序"详细地介绍了这两种排序算法的实现以及它们的优化策略。通过对原始算法的分析和改进,我们可以更好地理解和应用这些排序方法,并在实际编程中根据数据特性选择合适的排序算法,以...
在C++中实现冒泡排序,我们可以采用两种主要的方法:一种是传统的冒泡排序,另一种是优化过的冒泡排序,即添加了一个标志位来判断在一次遍历中是否进行了交换,如果未进行交换则说明序列已经有序,可以提前结束排序...
在这个"js代码-冒泡排序优化"的主题中,我们将深入探讨JavaScript实现冒泡排序的优化策略。 在原始的冒泡排序中,每次遍历时会检查每对相邻元素,如果它们的顺序错误,就交换位置。这个过程可能会导致大量的不必要...
4. **交换检查**:在一轮内层循环结束后,如果没有任何元素交换位置,说明数组已经完全排序,可以提前结束排序过程,这也是冒泡排序优化的一个关键点。 5. **重复步骤**:直到所有元素都按照从小到大的顺序排列,...
6. 冒泡排序的优化 - 优化一:设置一个标志位,如果在某一轮排序中没有发生任何交换,则说明数组已经有序,此时可以提前结束排序。 - 优化二:设置一个变量记录每一轮排序中最后一次元素交换的位置,该位置之后的...
System.out.println("冒泡排序优化前..."); int n = array.length; for (int i = 0; i ; i++) { for (int j = 0; j ; j++) { if (array[j] > array[j + 1]) { swap(array, j, j + 1); } } System.out....
然而,通过一些优化策略,可以提高冒泡排序的性能。 在优化冒泡排序的过程中,主要考虑两种策略:第一种是添加一个标志位,用于检查在某次遍历时是否发生了任何交换。如果没有发生交换,那么说明序列已经有序,无需...
根据给定的信息,本文将详细解释PHP中优化版本的冒泡排序算法,并深入探讨其工作原理、优化策略以及实现方式。 ### PHP优化版冒泡排序算法详解 #### 一、冒泡排序的基本概念 冒泡排序是一种简单的排序算法,通过...
冒泡排序是一种基础且经典的排序算法,主要用于对一组数值进行升序或降序排列。它的基本思想是通过不断地比较相邻元素并交换位置,使较大的(或较小的)元素逐渐“浮”到序列的尾部,就像水底下的气泡慢慢上升到水面...
4. **标志位**:为了优化冒泡排序,可以在每一轮遍历结束后设置一个标志位,如果在一轮遍历中没有发生过交换,说明数组已经是有序的,可以提前结束排序。 5. **代码实现**:以下是一个简单的C++冒泡排序示例: ```...
### 优化冒泡排序 尽管冒泡排序的效率相对较低,但可以通过一些策略来提高性能。例如,添加一个`boolean`标志`swapped`,在每次内层循环结束后检查是否发生过交换。如果没有交换,说明数组已经排序,可以提前结束...
冒泡排序是一种基础的计算机排序算法,它的工作原理是通过重复遍历要排序的数列,比较每对相邻元素,如果顺序错误就把它们交换过来。排序过程会重复进行,直到没有需要交换的元素为止,这时数列就完全排序好了。 ...