博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序算法(2)-冒泡排序及优化
阅读量:4060 次
发布时间:2019-05-25

本文共 3522 字,大约阅读时间需要 11 分钟。

1.冒泡排序

之前写过一个,其中总结了冒泡排序 .

冒泡排序的思想,是把相邻的元素两两比较,根据大小来交换元素的位置,每经过一轮的扫描,就会确定出一个最大的元素,即是一个元素有序.

原始的冒泡排序是稳定排序(如果一个数组中存在几个相同的元素,排序前后的相同元素的前后顺序不会发生变更,则认为排序是稳定的)。由于该排序算法的每一轮要遍历所有元素,轮转的次数和元素数量相当,所以时间复杂度是O(N^2) 。

代码如下:

/**     * @description 冒泡排序     * @author zhangdi     * @param arr     * @description : 两两比较,大的往后放; 每一次比较完成之后,下一次就少比较一个元素     *              第一次比较有0个元素不比较;第二次有一个元素不需要比较;第三次有两个元素不需要比较;     *              共需要比较arr.length-1次     */    public static void BubbleSort(int[] arr) {        int temp;// 临时变量        if (arr == null || arr.length == 0)            return;        for (int i = 0; i < arr.length - 1; i++) { // 表示趟数,一共arr.length-1次。            for (int j = arr.length - 1; j > i; j--) {                if (arr[j] < arr[j - 1]) {                    temp = arr[j];                    arr[j] = arr[j - 1];                    arr[j - 1] = temp;                }            }        }    }    /**     * @description 冒泡排序-2     * @param arr     * @author zhangdi     */    public static void BubbleSort2(int[] arr) {        int temp;// 临时变量        if (arr == null || arr.length == 0)            return;        for (int i = 0; i < arr.length - 1; i++) { // 表示趟数,一共arr.length-1次。            for (int j = 0; j < arr.length - 1 - i; j++) {                if (arr[j] > arr[j + 1]) {                    temp = arr[j];                    arr[j] = arr[j + 1];                    arr[j + 1] = temp;                }            }        }    }

2冒泡排序改进

现在我们思考一下,会发现这个算法还有优化的空间,比如说但是一个数组前一半部分已经是有序的,当某轮中没有发生元素交换,就可以确定,整个数组已经是有序的,此时就不需要进行接下来的扫描交换了.

/**     * @description 冒泡排序-1-优化     * @author zhangdi     * @param arr     *            * 针对问题:数据的顺序排好之后,冒泡算法仍然会继续进行下一轮的比较,直到arr.length-1次,后面的比较没有意义的。     *            方案: 设置标志位flag,如果发生了交换flag设置为true;如果没有交换就设置为false。     *            这样当一轮比较结束后如果flag仍为false,即:这一轮没有发生交换,说明数据的顺序已经排好,没有必要继续进行下去。     *      */    public static void BubbleSort1_better(int[] arr) {        int temp;// 临时变量        boolean flag;        if (arr == null || arr.length == 0)            return;        for (int i = 0; i < arr.length - 1; i++) { // 表示趟数,一共arr.length-1次。            flag = false;            for (int j = arr.length - 1; j > i; j--) {                if (arr[j] < arr[j - 1]) {                    temp = arr[j];                    arr[j] = arr[j - 1];                    arr[j - 1] = temp;                }            }            if (!flag)                break;        }    }

冒泡排序三改进

上面的算法还有优化的空间吗?答案是有,假如存在一个数组,前缀几个元素是无序的,而后面大部分皆是有序的,上面的版本并不能解决这种情况下出现的中间部分的反复的扫描,这些扫描交换的元素集中在数组前部.

多出来的时间消耗是后缀中已经有序的元素的反复的扫描交换,其实是不必要的;–>如何确定最后扫描交换的元素的标志在哪?而不是亦步亦趋的逐步收缩.
由此得出版本三

/**     * @description 冒泡排序-3     * @param arr     * @author zhangdi     */    private static void BubbleSort1_better(int[] array) {        int tmp = 0;        // 记录最后一次交换的位置        int lastExchangeIndex = 0;        // 无序数列的边界,每次比较只需要比到这里为止        int sortBorder = array.length - 1;        for (int i = 0; i < array.length; i++) {            // 有序标记,每一轮的初始是true            boolean isSorted = true;            for (int j = 0; j < sortBorder; j++) {                if (array[j] > array[j + 1]) {                    tmp = array[j];                    array[j] = array[j + 1];                    array[j + 1] = tmp;                    // 有元素交换,所以不是有序,标记变为false                    isSorted = false;                    // 把无序数列的边界更新为最后一次交换元素的位置                    lastExchangeIndex = j;                }            }            sortBorder = lastExchangeIndex;            if (isSorted) {                break;            }        }    }

转载地址:http://sawji.baihongyu.com/

你可能感兴趣的文章
【数据结构周周练】010 递归算法实现二叉树的创建与遍历
查看>>
【数据结构周周练】011 非递归算法实现二叉树的遍历
查看>>
【数据结构周周练】012 利用队列和非递归算法实现二叉树的层次遍历
查看>>
【数据结构周周练】013 利用栈和非递归算法求二叉树的高
查看>>
【数据结构周周练】014 利用栈和非递归算法求链式存储的二叉树是否为完全二叉树
查看>>
【数据结构周周练】015 利用递归算法创建链式存储的二叉树并转换左右孩子结点
查看>>
【数据结构周周练】016 利用递归算法及孩子兄弟表示法创建树、遍历树并求树的深度
查看>>
【数据结构周周练】017 利用递归算法及孩子兄弟表示法创建森林、遍历森林并求森林的叶子结点个数
查看>>
【数据结构必备基本知识】数据结构常用预定义常量、类型及头文件
查看>>
【数据结构周周练】018 利用递归算法及中序遍历将二叉树线索化并遍历
查看>>
【数据结构周周练】019 利用递归算法创建二叉排序树并遍历
查看>>
【数据结构周周练】020 二叉排序树的排序与迭代查找
查看>>
【数据结构周周练】035 利用递归判断一棵二叉树是否为二叉排序树
查看>>
【数据结构周周练】021 求某一个数据在二叉排序树中的层数
查看>>
【数据结构周周练】022 从大到小输出二叉排序树中小于某个值的所有结点编号及数据
查看>>
【数据结构必备基础知识】之图的基本概念详解
查看>>
【数据结构必备基本知识】图的存储结构(邻接矩阵、邻接表、十字链表、邻接多重表)详解
查看>>
【数据结构周周练】023 将图的邻接表表示转化为邻接矩阵表示的算法
查看>>
【数据结构周周练】024 图的经典遍历算法之深度优先搜索、广度优先搜素
查看>>
【数据结构周周练】025 查找算法详解及顺序查找算法实现
查看>>