牛骨文教育服务平台(让学习变的简单)
博文笔记

冒泡算法(两两比较,最小上冒)

创建时间:2017-02-24 投稿人: 浏览次数:488

假设排序数组a[n],按从小到大排列

int a[] = {1,5,3,6,2,4,9,2,0};
int length = a.length;

准备好交换方法

private void swap(int j, int i) {
    int temp = a[j];
    a[j] = a[i];
    a[i] = temp;
}

排序好后打印

for(int k = 0; k < length;k++){
    Log.e("tag",a[k] +"");
}

1.冒泡算法(两两比较,把小的往左移)

a[n] 和 a[n-1]比较,如果a[n-1] 大于 a[n] 则把a[n]和a[n-1]互换,这样a[n-1] < a[n]

接着再把a[n-1] 和a[n-2]比较。。。。。。。。。。。。。。。。a[n-2] < a[n-1]

。。。。。

最后把a[1]和a[0]比较。。。。。。。。。。。。。。。。。。。a[0] < a[1]

通过上述一轮比较,数组a最小的数被移到了最左边a[0]中,像泡泡冒到了最左边


以上是由a[n]到a[0]的比较,现在a[0]已排好

接下来进行a[n]到a[1]的比较,现在a[1]已排好

。。。。

最后a[n]到a[n-1]的比较,a[n-1]已排好


经过上述步骤,完成冒泡算法的排序

实现如下:

for(int i = 0; i < length;i++){
    for(int j = length-1;j > i;j--){
        if(a[j] < a[j-1]){
            swap(j,j-1);
        }
    }
}


改进:如果是{2,1,3,4,5,6,7}

经过a[n]到a[0]的第一次循环后,2和1交换,已全部排好序,后续的循环比较就没有必要了,所以我们设置一个标志位来进行控制:

boolean flag = true;
for(int i = 0; i < length  && flag;i++){
    flag = false;
    for(int j = length-1;j > i;j--){
        if(a[j] < a[j-1]){
            swap(j,j-1);
            flag = true;
        }
    }
}
如果中途排序好了,就不会再进入a[j] < a[j-1] if分支,flag就为false值,将退出循环比较流程


算法评估:如果为最糟情况,数组刚好是从大到小排序的,用冒泡算法实现从小到大的排序

则比较交换次数是(n-1) + (n-2) + (n-3)+。。。。 + 1 = n(n +1)/2

时间复杂度为O(n^2)



声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。