八大排序-冒泡排序

概要

冒泡排序算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。冒泡排序是八大排序中的入门级排序算法,也是算法入门中比较经典的排序算法。本篇系统介绍下冒泡排序的原理以及实现。

原理

循环对比数组中前后相邻的两个元素,将较大的数交换移动到后面,一趟排序之后最大的数会被移动到最末尾。然后排除最末尾最大数,继续循环将最大数移动到末尾,最终保证数组有序。

一趟排序

以数组int n[] = { 6, 5, 2, 7, 1 }为例:


八大排序-冒泡排序_第1张图片
image
  • 第一次6和5对比,较大的数字6与5交换;
  • 第二次6和2对比,较大的数字6继续与2交换;
  • 第三次6和7对比,较大的数字7无需交换;
  • 第四次7和1对比,较大的数字7和1交换;

一趟排序后数组中最大的数字7位于数组末位

多趟排序控制

一趟排序后最大数字位与末位,通过控制数组下标大小,每次循环将需要排序数组个数减小一个,从而使得一趟排序后剔除当前最大元素后,继续对比交换依次将最大数字移动至末位:


八大排序-冒泡排序_第2张图片
image
  • 第一趟排序将最大数字7移动至末位;
  • 第二趟排序将7之前最大数字6移动至倒数第2位;
  • 第三趟排序将6之前最大数字5移动至倒数第3位;
  • 第四趟排序将5之前最大数字2移动至倒数第4位(第2位);

编码实践

public class Test {

    public static void main(String[] args) {
        int n1[] = { 6, 5, 2, 7, 1 };
        bubbleSort1(n1);
        System.out.print("冒泡排序方法一结果:");
        for (int m : n1) {
            System.out.print(m + " ");
        }
        System.out.println("");
        int n2[] = { 6, 5, 2, 7, 1 };
        bubbleSort1(n2);
        System.out.print("冒泡排序方法二结果:");
        for (int m : n2) {
            System.out.print(m + " ");
        }
        System.out.println("");
        int n3[] = { 6, 5, 2, 7, 1 };
        bubbleSort1(n3);
        System.out.print("冒泡排序方法三结果:");
        for (int m : n3) {
            System.out.print(m + " ");
        }
    }

    public static void bubbleSort1(int n[]) {
        for (int i = n.length - 1; i >= 0; i--) {
            for (int j = 0; j < i; j++) {
                if (n[j] > n[j + 1]) {
                    int temp = n[j];
                    n[j] = n[j + 1];
                    n[j + 1] = temp;
                }
            }
        }
    }

    public static void bubbleSort2(int n[]) {
        for (int i = n.length - 1; i >= 0; i--) {
            for (int j = 0; j < i; j++) {
                if (n[j] > n[j + 1]) {
                    n[j] ^= n[j + 1];
                    n[j + 1] ^= n[j];
                    n[j] ^= n[j + 1];
                }
            }
        }
    }

    public static void bubbleSort3(int n[]) {
        boolean isSort = false;
        for (int i = n.length - 1; i >= 0 && !isSort; i--) {
            isSort = true;
            for (int j = 0; j < i; j++) {
                if (n[j] > n[j + 1]) {
                    n[j] ^= n[j + 1];
                    n[j + 1] ^= n[j];
                    n[j] ^= n[j + 1];
                    isSort = false;
                }
            }
        }
    }
}
  • 结果
冒泡排序方法一结果:1 2 5 6 7 
冒泡排序方法二结果:1 2 5 6 7 
冒泡排序方法三结果:1 2 5 6 7 

说明

上述三种冒泡排序的编码实践方法中,第一种是冒泡排序最基础的写法;第二种使用位运算优化交换数字的效率;第三方法,利用标记位判定数组是否已经有序从而避免对有序数组的遍历进一步优化效率。

彩蛋

方法二bubbleSort2中交换数字使用的位运算:

n[j] ^= n[j + 1];
n[j + 1] ^= n[j];
n[j] ^= n[j + 1];

交换的原理是?这便是本篇的彩蛋。

结语

冒泡排序是最简单的排序算法之一,本篇重点介绍冒泡排序算法思想原理以及实现。进一步又介绍了冒泡的优化小技巧,理解本篇后相信日后再遇见手写冒泡排序的场景会更加得心应手,学无止境。最后,如果觉得本篇对你有所启发或帮助,不妨关注走一波0.0

八大排序-冒泡排序_第3张图片
关注订阅号 获取更多干货~

你可能感兴趣的:(八大排序-冒泡排序)