【笔记16】排序算法:冒泡排序

简介: 排序:把一串没有按照顺序排列的数按照升序或降序排列。排序前:1、6、2、7、8、3、9、5、4升序:1、2、3、4、5、6、7、8、9降序:9、8、7、6、5、4、3、2、1

一、初始排序(Sorting)

排序:把一串没有按照顺序排列的数按照升序或降序排列。

排序前:1、6、2、7、8、3、9、5、4
升序:1、2、3、4、5、6、7、8、9
降序:9、8、7、6、5、4、3、2、1

二、十大排序算法

01、冒泡排序(Bubble Sort)
02、选择排序(Selection Sort)
03、插入排序(Insertion Sort)
04、归并排序(Merge Sort)
05、快速排序(Quick Sort)
06、希尔排序(Shell Sort)
07、堆排序(Heap Sort)
08、基数排序(Radix Sort)
09、桶排序(Bucket Sort)
10、计数排序(Counting Sort)

三、冒泡排序(Bubble Sort)介绍

数据结构可视化 https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

思想:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。

① 从头开始比较每一对相邻的元素,如果第1个比第2个大就交换它们的位置。

② 执行完一轮后,最末尾的那个元素是整个数列中最大的元素。

③ 忽略 ① 中找到的最大元素,重复执行步骤 ①,直到全部元素有序。
在这里插入图片描述

四、Java 代码实现

/**
 * 冒泡排序
 */
public class BubbleSort {

    public static void main(String[] args) {
        int[] nums = {1, 6, 2, 7, 8, 3, 9, 5, 4};

        for (int end = nums.length; end > 0; end--) {
            for (int begin = 1; begin < end; begin++) {
                if (nums[begin] < nums[begin - 1]) {
                    int temp;
                    temp = nums[begin];
                    nums[begin] = nums[begin - 1];
                    nums[begin - 1] = temp;
                }
            }
        }
    }

}

五、问题讨论

(1) 如果数列本身已经完全有序

如果数列本身已经完全有序,可提前终止冒泡排序。

/**
 * 冒泡排序
 */
public class BubbleSort {

    public static void main(String[] args) {  
        for (int end = nums.length; end > 0; end--) {
            boolean noSwap = true;
            for (int begin = 1; begin < end; begin++) {
                if (nums[begin] < nums[begin - 1]) { // true: 执行交换
                    int temp;
                    temp = nums[begin];
                    nums[begin] = nums[begin - 1];
                    nums[begin - 1] = temp;
                    noSwap = false;
                }
            }
            if (noSwap) break;
        } 
    }
 
}

(2) 如果数列尾部已经局部有序

如果数列尾部已经局部有序,可记录最后一次交换的位置,减少比较次数。
在这里插入图片描述

    public static Integer[] bubble3(Integer[] nums) {
       for (int end = nums.length; end > 0; end--) {
           // lastSwapIdx 的初始值在数组完全有序的时候有用
           int lastSwapIdx = 1; // 最后一次交换的位置
           for (int begin = 1; begin < end; begin++) {
               if (nums[begin] < nums[begin - 1]) {
                   int temp;
                   temp = nums[begin];
                   nums[begin] = nums[begin - 1];
                   nums[begin - 1] = temp;
                   lastSwapIdx = begin;
               }
           }
           end = lastSwapIdx;
       }
       return nums;
   }

六、相关工具类

public class QYIntegers {

    /**
     * 生成任意范围内的任意个随机正整数
     *
     * @param number 随机数个数
     * @param start  起始范围
     * @param end    结束范围
     * @return 随机数数组
     */
    public static Integer[] createRandom(Integer number, Integer start, Integer end) {
        if (number == null || number < 2) number = 8;
        if (start == null || start < 0) start = 0;
        if (end == null || end < 3) end = 3;

        Integer[] randoms = new Integer[number];

        for (Integer i = 0; i < number; i++) {
            randoms[i] = new Random().nextInt(end - start) + start;
        }

        return randoms;
    }

    /**
     * 打印整数数组
     *
     * @param numArr  要打印的数组
     * @param delimit 每个数之间的分隔符
     */
    public static void printIntArr(Integer[] numArr, String delimit) {
        StringBuilder sBuilder = new StringBuilder();
        for (Integer num : numArr) {
            sBuilder.append(num).append(delimit);
        }
        System.out.println(sBuilder.toString());
    }

    public static void printIntArr(Integer[] numArr) {
        printIntArr(numArr, "_");
    }

    /**
     * 拷贝整型数组
     */
    public static Integer[] copyInt(Integer[] ints) {
        Integer[] newInts = new Integer[ints.length];
        for (int i = 0; i < ints.length; i++) {
            newInts[i] = ints[i];
        }
        return newInts;
    }

}
/**
 * 测试某段代码的执行花费了多少时间
 */
public class Times {
    private static final SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss.SSS");

    public interface Task {
        void execute();
    }

    public static void test(String title, Task task) {
        if (task == null) return;
        title = (title == null) ? "" : ("【" + title + "】");
        System.out.println(title);
        System.out.println("开始:" + fmt.format(new Date()));
        long begin = System.currentTimeMillis();
        task.execute();
        long end = System.currentTimeMillis();
        System.out.println("结束:" + fmt.format(new Date()));
        double delta = (end - begin) / 1000.0;
        System.out.println("耗时:" + delta + "秒");
        System.out.println("-------------------------------------");
    }
}
相关文章
|
4天前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
5天前
|
机器学习/深度学习 存储 算法
【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解
【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解
|
5天前
|
搜索推荐 算法 Python
python实现冒泡排序算法
python实现冒泡排序算法
27 0
|
4天前
|
搜索推荐 算法 Java
sort-01-bubble sort 冒泡排序算法详解
这是一个关于排序算法的系列文章摘要。作者整理了10种不同的排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序和大文件外部排序。文章详细介绍了冒泡排序的工作原理、流程,并提供了代码实现,强调了在实现中考虑的改进点,如统一接口、实用性增强和日志输出。此外,还提供了一个排序接口和工具类以方便使用,并通过测试代码和日志展示了排序过程。整个系列旨在帮助读者理解和掌握排序算法。相关代码已开源在GitHub。
|
5天前
|
存储 算法 搜索推荐
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
【数据结构与算法】归并排序(详解:递归与非递归的归并排序 | 赠:冒泡排序和选择排序)
|
4天前
|
搜索推荐 算法 Java
Java基础(冒泡排序算法)
Java基础(冒泡排序算法)
20 3
|
4天前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--快速排序
数据结构与算法(Java篇)笔记--快速排序
|
5天前
|
机器学习/深度学习 算法 搜索推荐
数据结构与算法(Java篇)笔记--归并排序
数据结构与算法(Java篇)笔记--归并排序
|
5天前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--选择排序
数据结构与算法(Java篇)笔记--选择排序
|
5天前
|
搜索推荐 算法 C语言
C语言实现冒泡排序算法
C语言实现冒泡排序算法
19 0