冒泡排序的详细解析

1、基本思想

冒泡排序顾名思义就是整个过程像气泡一样往上升,单向冒泡排序的基本思想是(假设由小到大排序):对于给定n个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换位置,进行一轮比较和换位后,n个记录的最大记录将位于第n位,然后对前(n-1)个记录进行第二轮比较;重复该过程,直到记录剩下一个为止。

2、复杂度分析

当最好的情况,也就是要排序的序列本身就是有序的,需要进行(n-1)次比较,没有数据交换,时间复杂度为O(n).

当最坏的情况,即待排序的表是逆序的情况,此时需要比较次数为:1+2+3+…+(n-1)=n(n-1)/2次,并作等数量级的记录移动,因此总的时间复杂度为O(n^2)。

无论在何种情况下,冒泡排序空间复杂度(额外空间)总是O(1)。

3、排序过程如下

以数组{49,38,65,97,76,13,27,49}为例

从小到大:

冒泡排序的详细解析_第1张图片
冒泡排序的详细解析_第2张图片

从大到小:49,38,65,97,76,13,27,49


冒泡排序的详细解析_第3张图片


冒泡排序的详细解析_第4张图片

4  java代码实现

public static void bubbleSort(int[] arr)

{

for(int i=0; i < arr.length-1;i++){

for(int j=0; j < arr.length-i-1;j++)

if(arr[j] > arr[j+1])

{

inttemp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

location = j;

}

}

}

代码优化

1 当某一趟遍历没有交换,就说明已经遍历好了,就不用再迭代了

public static void sort(int[] arr)

{

int flag;// 标记

for(int i=0; i < arr.length-1;i++){

flag =1;// 每一次迭代标记为1

for(int j=0; j < arr.length-i-1;j++)

{

if(arr[j] > arr[j+1])

{

inttemp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

flag =0;// 如果有次序交换,标记为0

}

}

if(flag ==1)// 没有次序交换,排序完成

break;

}



2 记录每次遍历数据之后交换次序的位置,显然这个位置之后的数据已经有序了不用再排序了。因此通过记录最后发生数据交换的位置就可以确定下次循环的范围了。

public static void sort(int[] arr)

{

intlocation;// 标记

intn = arr.length -1;// 初始化最后交换位置为最后一个元素

for(int i=0; i < arr.length-1;i++){

{

location = n;// 记录最后发生交换的位置

for(int j=0; j < arr.length-i-1;j++)

{

if(arr[j] > arr[j+1])

{

inttemp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

n = j;// 记录无序位置的结束 ,有序从j+1位置开始

}

}

if(n == location)// 没有次序交换,排序完成

break;

}

}


实际上,由于在大量数据的情况下几乎不使用冒泡排序,而使用小数据的时候增加的布尔变量反而会造成额外的开销。所以个人认为上面改进后的算法只是纯理论的,通常,冒泡排序就写前面一种就行了。

算法稳定性

容易看出,在相邻元素相等时,我们并不需要交换它们的位置,所以,冒泡排序是稳定排序。

算法适用场景

冒泡排序思路简单,代码也简单,特别适合小数据的排序。但是,由于算法复杂度较高,在数据量大的时候不适合使用。如果一定要在较多数据的时候使用,最好对算法加以改进,例如选择排序法。

你可能感兴趣的:(冒泡排序的详细解析)