算法01 七大排序之:冒泡排序和快速排序

排序是我们生活中经常会面对的问题。同学们做操时会按照从矮到高排列;老师查看上课出勤情况时,会按学生学号顺序点名;高考录取时,会按成绩总分降序依次录取等。排序是数据处理中经常使用的一种重要的运算,它在我们的程序开发中承担着非常重要的角色。

排序分为以下四类共七种排序方法:

交换排序:

  ① 冒泡排序    ② 快速排序

选择排序:

  ③ 直接选择排序    ④ 堆排序

插入排序:

  ⑤ 直接插入排序    ⑥ 希尔排序

合并排序:

  ⑦ 合并排序

这篇文章主要总结的是交换排序(即冒泡排序和快速排序),交换排序的基本思想是:两两比较待排序元素,如果发现两个元素的次序相反时即进行交换,直到所有元素都没有反序时为止。我会从以下几个方面进行总结:

1、冒泡排序及算法实现

2、快速排序及算法实现

3、冒泡排序VS快速排序

1、冒泡排序及算法实现

什么是冒泡排序呢?冒泡排序是一种简单的排序方法,它的基本思想是:通过相邻两个元素之间的比较和交换,使较大的元素逐渐从前面移向后面(升序),就像水底下的气泡一样逐渐向上冒泡,所以被称为“冒泡”排序。冒泡排序的最坏时间复杂度为O(n2),平均时间复杂度为O(n2)

下面以一张图来展示冒泡排序的全过程,其中方括号内为下一轮要排序的元素,方括号后面的第一个元素为本轮排序浮出来的最大元素。

1-1、示意图

1-2、代码

冒泡排序算法的代码实现:

BubbleSort.java

public class BubbleSort {
    public static void main(String[] args) {
        int[] list = {36, 28, 45, 13, 67, 37, 18, 56};
        System.out.println("************冒泡排序************");
        System.out.println("排序前:");
        display(list);

        System.out.println("排序后:");
        bubbleSort(list);
        display(list);
    }

    /**
     * 遍历打印
     */
    public static void display(int[] list) {
        System.out.println("********展示开始********");
        if (list != null && list.length > 0) {
            for (int num :
                    list) {
                System.out.print(num + " ");
            }
            System.out.println("");
        }
        System.out.println("********展示结束********");
    }

    /**
     * 冒泡排序算法
     */
    public static void bubbleSort(int[] list) {
        int temp;
        // 做多少轮排序(最多length-1轮)
        for (int i = 0; i < list.length - 1; i++) {
            // 每一轮比较多少个
            for (int j = 0; j < list.length - 1 - i; j++) {
                if (list[j] > list[j + 1]) {
                    // 交换次序
                    temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                }
            }
        }
    }
}

测试结果:

2、快速排序及算法实现 

快速排序(Quick Sort) 是对冒泡排序的一种改进方法,在冒泡排序中,进行元素的比较和交换是在相邻元素之间进行的,元素每次交换只能移动一个位置,所以比较次数和移动次数较多,效率相对较低。而在快速排序中,元素的比较和交换是从两端向中间进行的,较大的元素一轮就能够交换到后面的位置,而较小的元素一轮就能交换到前面的位置,元素每次移动的距离较远,所以比较次数和移动次数较少,速度较快,故称为“快速排序”。

快速排序的基本思想是:通过一轮排序将待排序元素分割成独立的两部分, 其中一部分的所有元素均比另一部分的所有元素小,然后分别对这两部分的元素继续进行快速排序,以此达到整个序列变成有序序列。快速排序的最坏时间复杂度为O(n2),平均时间复杂度为O(n*log2n)   

2-1、示意图

2-2、代码

快速排序算法的代码实现:

QuickSort.java 

public class QuickSort {
    public static void main(String[] args) {
        int[] list = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
        System.out.println("************快速排序************");
        System.out.println("排序前:");
        display(list);

        System.out.println("排序后:");
        quickSort(list, 0, list.length - 1);
        display(list);
    }

    /**
     * 快速排序算法
     */
    public static void quickSort(int[] list, int left, int right) {
        if (left < right) {
            // 分割数组,找到分割点
            int point = partition(list, left, right);

            // 递归调用,对左子数组进行快速排序
            quickSort(list, left, point - 1);
            // 递归调用,对右子数组进行快速排序
            quickSort(list, point + 1, right);
        }
    }

    /**
     * 分割数组,找到分割点
     */
    public static int partition(int[] list, int left, int right) {
        // 用数组的第一个元素作为基准数
        int first = list[left];
        while (left < right) {
            while (left < right && list[right] >= first) {
                right--;
            }
            // 交换
            swap(list, left, right);

            while (left < right && list[left] <= first) {
                left++;
            }
            // 交换
            swap(list, left, right);
        }
        // 返回分割点所在的位置
        return left;
    }

    /**
     * 交换数组中两个位置的元素
     */
    public static void swap(int[] list, int left, int right) {
        int temp;
        if (list != null && list.length > 0) {
            temp = list[left];
            list[left] = list[right];
            list[right] = temp;
        }
    }

    /**
     * 遍历打印
     */
    public static void display(int[] list) {
        System.out.println("********展示开始********");
        if (list != null && list.length > 0) {
            for (int num :
                    list) {
                System.out.print(num + " ");
            }
            System.out.println("");
        }
        System.out.println("********展示结束********");
    }
}

测试结果:

3、冒泡排序VS快速排序

代码如下:

BubbleVsQuick.java 

public class BubbleVsQuick {

    public static void main(String[] args) {
        testQuick();
        testBubble();
    }

    /**
     * 测试快速排序耗费的时间
     */
    public static void testQuick() {
        int[] list = new int[10000];
        for (int i = 0; i < 10000; i++) {
            list[i] = (int) (Math.random() * 100000);
        }

        // 快速排序
        long start = System.currentTimeMillis();
        QuickSort.quickSort(list, 0, list.length - 1);
        long end = System.currentTimeMillis();
        System.out.println("快速排序耗费的时间:" + (end - start));
        display(list);
    }

    /**
     * 测试冒泡排序耗费的时间
     */
    public static void testBubble() {
        int[] list = new int[10000];
        for (int i = 0; i < 10000; i++) {
            list[i] = (int) (Math.random() * 100000);
        }

        // 冒泡排序
        long start = System.currentTimeMillis();
        BubbleSort.bubbleSort(list);
        long end = System.currentTimeMillis();
        System.out.println("冒泡排序耗费的时间:" + (end - start));
        display(list);
    }

    /**
     * 遍历打印前10个数
     */
    public static void display(int[] list) {
        System.out.println("********排序之后的前10个数start********");
        if (list != null && list.length > 0) {
            for (int i = 0; i < 10; i++) {
                System.out.print(list[i] + " ");
            }
            System.out.println("");
        }
        System.out.println("********排序之后的前10个数end**********");
        System.out.println("");
    }
}

测试结果:

可见,快速排序的速度比冒泡排序更快。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏noteless

[八]基础数据类型之Double详解

这些属性,看过浮点数简介的话,可以很清晰的理解,再次说明下,但凡本人的系列文章,全部都是有顺序的

1.1K10
来自专栏java一日一条

八大排序算法

(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一...

7510
来自专栏向治洪

算法笔记之排序

最近在看《算法笔记》,如果单从算法来说,这本书真正做到了短小精悍,首先以排序入题,那么我们今天也来说说排序。 排序 将一堆杂乱无章的元素按照某种规则有序排列的过...

234100
来自专栏Jack的Android之旅

疯狂java笔记之常用的内部排序

在计算机程序开发过程中,经常需要一组数据元素(或记录)按某个关键字进行排序,排序完成的序列可用于快速查找相关记录。

7310
来自专栏积累沉淀

必须掌握的八种排序(7-8)--归并排序,基数排序

7、归并排序 (1)基本排序:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后...

23450
来自专栏程序员互动联盟

【编程基础】零基础学习Java之运算符

学习计算机编程语言都会遇到运算符这一知识点,运算符这个知识点是教怎么运用编程语言进行最基本的数据处理,下面就讲一下在Java语言中运算符是怎么回事。 1、算术运...

413100
来自专栏老九学堂

嘀 , 嘀嘀 ... 常用排序算法再总结

  这篇文章中再和小伙伴们来探讨一下常用的非比较排序算法:计数排序,基数排序,桶排序。在一定条件下,它们的时间复杂度可以达到O(n)。

13230
来自专栏我就是马云飞

【数据结构】七大排序算法

排序的相关概念 排序的分类 根据在排序过程中带排序的记录是否全部被放置在内存中,排序分为: 内排序 外排序 1.内排序 内排序是在排序整个过程中,带排序的所有...

209100
来自专栏Android开发指南

2 :基本语法

369110
来自专栏jeremy的技术点滴

排序算法python实现

38890

扫码关注云+社区

领取腾讯云代金券