冒泡排序
排序思想
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
算法步骤:
第一步:比较相邻元素,如果第一个比第二个大,就交换他们。
for(int begin =0;begin<arr.length-1;begin++) {
int temp = 0;
if (arr[begin] > arr[begin + 1]) {
temp = arr[begin];
arr[begin] = arr[begin + 1];
arr[begin + 1] = temp;
}
}
第二步:经过第一步可以看出结果最大的元素已经排到了最后面,接下来要做的就 是除去最后一个元素,将数组重复上面的过程,依次循环即可
for(int end = arr.length-1;end>0;end--){
for(int begin =0;begin<end;begin++) {
int temp = 0;
if (arr[begin] > arr[begin + 1]) {
temp = arr[begin];
arr[begin] = arr[begin + 1];
arr[begin + 1] = temp;
}
}
优化冒泡
当输入一个局部有序数组时,列入这样 [3,2,1,4,5,6], 可以看出后面4 5 6是已经排好序的,但是上面代码仍要每次判断后面数字大小,这样就会造成时间浪费,所以优化思路就是: 在每次遍历结束后设置临时变量记录一下最后交换的位置,所谓最后交换就是后面数据已经经过比较但是没有发生交换,说明后面局部元素已经排好序,那么我们下次遍历就不访问已经排好的元素,将临时变量赋值给下次遍历的终点值。
for(int end = arr.length-1;end>0;end--){
int indexend =0;//临时变量记录最后一次交换位置
for(int begin =0;begin<end;begin++) {
int temp = 0;
if (arr[begin] > arr[begin + 1]) {
temp = arr[begin];
arr[begin] = arr[begin + 1];
arr[begin + 1] = temp;
indexend =begin+1;//将最后一次交换位置赋值给临时变量
}
}
end= indexend;//临时变量位置后面已经局部排好序
}
综上整理出测试代码
public static void main(String[] args) {
int[] arr =new int[]{3,2,1,4,5,6};
GuluSort.sortYouHua(arr);
}
public static void sortYouHua(int[] arr){
for(int end = arr.length-1;end>0;end--){
int indexend =0;//临时变量记录最后一次交换位置
for(int begin =0;begin<end;begin++) {
int temp = 0;
if (arr[begin] > arr[begin + 1]) {
temp = arr[begin];
arr[begin] = arr[begin + 1];
arr[begin + 1] = temp;
indexend =begin+1;//将最后一次交换位置赋值给临时变量
}
}
end= indexend;//临时变量位置后面已经局部排好序
}
System.out.println(Arrays.toString(arr));
}
时间复杂度
最坏、平均时间复杂度: O(N^2)
最好书记兼复杂度 O(N)
空间复杂度
O(1)
冒泡稳定性
稳定性概念: 如果两个相等的元素,在排序前后的相对位置保持不变,那么这就 是稳定的排序算法。
冒泡属于稳定算法,因为两个元素相互比较判断出大小才交换,但是注意细节有一种危险的写法最终可以实现排序但是最终是不稳定的,这种情况就是判断大小的时候用了等于号。
if (arr[begin] > arr[begin + 1])
正确写法
if (arr[begin] >= arr[begin + 1])
错误写法
冒泡是否是原地算法
何为原地算法:不依赖额外的资源或则以来少数额外资源,仅依靠输出来覆盖(简单来说就是空间复杂度低)
那么可以看出冒泡排序是原地算法(In -place)。