常见排序算法:冒泡排序

常见排序算法:冒泡排序

算法原理

冒泡排序 原理(升序为例)就是将较小的值逐步“浮出水面”,较大的值逐步“沉入水底”的过程,利用双层嵌套的循环,每次比较相邻两个数据的大小,小值上浮,大值下沉,相等则位置不变。

算法分析

对于一个包含n个数据的数组,最坏情况下,需进行n-1次排序。
第一次排序:依次比较0和1、1和2、…、n-2和n-1索引的元素,若前值>后值则交换数据,否则数据不变。遍历完成后,最大值“沉入水底”,即索引n-1处为最大值;
第二次排序:依次比较0和1、1和2、…、n-3和n-2索引的元素,若前值>后值则交换数据,否则数据不变。遍历完成后,第二大值“沉入水底”,即索引n-1处为第二大值;
……
第n-1次排序:比较0和1索引的元素,若前值>后值则交换数据,否则数据不变。遍历完成后,最小值“浮出水面”,即索引0处为最小值。
假设数组为:a[6] = {21,30,47,30,1,2};
初始:21,30,47,30,1,2
第一次排序:21,30,30,1,2,47
第二次排序:21,30,1,2,30,47
第三次排序:21,1,2,30,30,47
第四次排序:1,2,21,30,30,47
第五次排序:1,2,21,30,30,47

算法总结

空间复杂度:O(1)
时间复杂度:O(n^2)
稳定性:稳定,上例可知,排序过程中30和30的相对位置稳定
优点:算法思路简单、容易实现
缺点:时间复杂度较高,效率低,存在无效排序的情况
优化:设置一个标记属性,一旦某次排序没有交换发生,即可提前结束排序,可减少无效的排序次数

算法实现-Java

package sort;


/**
 * Created by FengJialong on 2019/6/21.
 */
public class BubbleSort {
    public static void main(String[] args) {
        bubbleSort();
        bubbleSortOptimize();
    }
    public static void bubbleSort() {
        int[] arrays = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
        int changeTime = 0;
        for (int i = 0; i < arrays.length; i++) { // 比较次数
            changeTime++;
            for (int j = 0; j < (arrays.length - 1 - i); j++) {
                if (arrays[j] > arrays[j + 1]) {
                    swap(arrays, j, j + 1);
                }
            }
            sysOut(arrays);
        }
        System.out.println("优化前排序次数:" + changeTime);
    }

    public static void bubbleSortOptimize() {
        int[] arrays = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
        int changeTime = 0;
        for (int i = 0; i < arrays.length; i++) { // 比较次数
            boolean flag = true;
            changeTime++;
            for (int j = 0; j < (arrays.length - 1 - i); j++) {
                if (arrays[j] > arrays[j + 1]) {
                    swap(arrays, j, j + 1);
                    flag = false;
                }
            }
            sysOut(arrays);
            if (flag) { //如果整次循环未发生交换,则跳出
                break;
            }
        }

        System.out.println("优化后排序次数:" + changeTime);
    }

    private static void sysOut(int[] a) {
        StringBuilder stringBuilder = new StringBuilder("");
        for (int i = 0; i < a.length; i++) {
            stringBuilder.append(a[i]).append(",");
        }
        System.out.println(stringBuilder.substring(0, stringBuilder.length() - 1).toString());
    }

    private static void swap(int[] a, int x, int y) {
        int temp = a[x];
        a[x] = a[y];
        a[y] = temp;
    }
}

执行结果

3,38,5,44,15,36,26,27,2,46,4,19,47,48,50
3,5,38,15,36,26,27,2,44,4,19,46,47,48,50
3,5,15,36,26,27,2,38,4,19,44,46,47,48,50
3,5,15,26,27,2,36,4,19,38,44,46,47,48,50
3,5,15,26,2,27,4,19,36,38,44,46,47,48,50
3,5,15,2,26,4,19,27,36,38,44,46,47,48,50
3,5,2,15,4,19,26,27,36,38,44,46,47,48,50
3,2,5,4,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
优化前排序次数:15
3,38,5,44,15,36,26,27,2,46,4,19,47,48,50
3,5,38,15,36,26,27,2,44,4,19,46,47,48,50
3,5,15,36,26,27,2,38,4,19,44,46,47,48,50
3,5,15,26,27,2,36,4,19,38,44,46,47,48,50
3,5,15,26,2,27,4,19,36,38,44,46,47,48,50
3,5,15,2,26,4,19,27,36,38,44,46,47,48,50
3,5,2,15,4,19,26,27,36,38,44,46,47,48,50
3,2,5,4,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
2,3,4,5,15,19,26,27,36,38,44,46,47,48,50
优化后排序次数:10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值