vlambda博客
学习文章列表

十大经典排序--冒泡排序及其优化

冒泡排序思路:



  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

  • 针对所有的元素重复以上的步骤,除了最后一个。

  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。


动画图:



代码:

 1public void BubbleSort(int[] arr) {
2    int length = arr.length;
3    //确定排序趟数
4    for (int i = 0; i < length - 1; i++) {
5        //确定比较次数
6        for (int j = 0; j < length - 1 - i; j++) {
7            if (arr[j] > arr[j + 1]) {
8                //交换
9                int tmp = arr[j];
10                arr[j] = arr[j + 1];
11                arr[j + 1] = tmp;
12            }
13        }
14    }
15}


优化一:


思路:假设我们现在排序ar[]={1,2,3,4,5,6,7,8,10,9}这组数据,按照上面的排序方式,第一趟排序后将10和9交换已经有序,接下来的8趟排序就是多余的,什么也没做。

所以我们可以在交换的地方加一个标记,如果那一趟排序没有交换元素,说明这组数据已经有序,不用再继续下去。


代码:

 1public void BubbleSort(int[] arr) {
2    int length = arr.length;
3    //确定排序趟数
4    for (int i = 0; i < length - 1; i++) {
5        //是否发生比较
6        boolean flag = false;
7        //确定比较次数
8        for (int j = 0; j < length - 1 - i; j++) {
9            if (arr[j] > arr[j + 1]) {
10                //交换
11                int tmp = arr[j];
12                arr[j] = arr[j + 1];
13                arr[j + 1] = tmp;
14                flag = true;
15            }
16        }
17        //没有发生变化比较 说明已经有序
18        if (!flag) {
19            break;
20        }
21    }
22}


优化二:

思路:优化一仅仅适用于连片有序而整体无序的数据(例如:1, 2,3 ,4 ,7,6,5)。但是对于前面大部分是无序而后边小半部分有序的数据(1,2,5,7,4,3,6,8,9,10)排序效率也不可观

针对这类情况,咱们可以继续优化,即咱们可以记下最后一次交换的位置,后边没有交换,必然是有序的,然后下一次排序从第一个比较到上次记录的位置结束即可


代码:

 1public void BubbleSort(int[] arr) {
2    int length = arr.length;
3    int k = length - 1;
4    int pos = 0;//用来记录最后一次交换的位置
5    //确定排序趟数
6    for (int i = 0; i < length - 1; i++) {
7        //是否发生比较
8        boolean flag = false;
9        //确定比较次数
10        for (int j = 0; j < k; j++) {
11            if (arr[j] > arr[j + 1]) {
12                //交换
13                int tmp = arr[j];
14                arr[j] = arr[j + 1];
15                arr[j + 1] = tmp;
16                flag = true;
17                //更新最后一次比较位置
18                pos = j;
19            }
20        }
21        //没有发生变化比较 说明已经有序
22        if (!flag) {
23            break;
24        }
25        //下一次比较到记录位置即可
26        k = pos;
27    }
28}



时间复杂度:O(n2),优化后最好能达到O(n)

空间复杂度:O(1)


以上仅是个人思路解法,觉得还不错欢迎点赞关注分享


往期精彩推荐