数据结构和算法——排序算法(2)——基于比较的O(n^2)的排序算法(2)——选择排序、插入排序

本文详细介绍了选择排序和插入排序的基本思想、图解原理、Java代码实现及性能分析。选择排序通过n-1次选择最小值交换,而插入排序通过插入操作将无序表元素有序化。文章还讨论了插入排序的优化——折半插入排序,并提供了性能测试代码,揭示了不同排序算法在不同数据输入下的表现。
摘要由CSDN通过智能技术生成

目录

1.选择排序

1.1 基本思想

1.2 图解原理:

1.3 Java代码实现

1.4 性能分析

2.插入排序

2.1 基本思想

2.2 图解原理

2.3 代码实现

2.4 优化——折半插入排序

2.5 性能测试

(1)直接插入排序和选择排序性能测试代码:(输入数据为随机数据)

(2)直接插入排序和折半插入排序性能测试代码:(输入数据为随机数据)

3.三种基于比较的O(n^2)的排序算法总结


分享一个超级好的理解算法的网站(会以动画的形式显示每一步执行结果):https://visualgo.net/en

1.选择排序

1.1 基本思想

  • 第一次从arr[0]~arr[n-1]中选取最小值,与arr[0]交换,
  • 第二次从arr[1]~arr[n-1]中选取最小值,与arr[1]交换
  • ......
  • 第i次从arr[i-1]~arr[n-1]中选取最小值,与arr[i-1]交换
  • ......
  • 第n-1次从arr[n-2]~arr[n-1]中选取最小值,与arr[n-2]交换
  • 总共通过n-1次,得到一个从小到大排列的有序序列
  • 之所以叫选择排序,是因为它在不断地选择剩余元素之中的最小者

1.2 图解原理:

小结:

  • 一共进行n-1次排序(n为数组的长度)
  • 冒泡排序是从未排序的数组中把最大值交换到未排序的最右边,而选择排序是每次从未排序的序列中选出最小值放置在未排序的最左边
  • 每次排序都要进行一次交换,每次交换都能确定一个元素,所以算法的时间效率取决于比较的次数

1.3 Java代码实现

import java.util.Arrays;

public class SelectionSort extends Sort{

    @Override
    public void sort(Comparable[] arr) {
        int min = 0;   //用来存放每一趟的最小值

        //外部循环为排序次数
        for (int i = 0; i < arr.length-1; i++)
        {
            min = i;
            //每一趟将未排序的数组遍历比较每个元素与最小值来找出最小值所在位置的索引
            for (int j = i; j < arr.length; j++)    //这里不存在访问j+1的情况,而是要将数组访问完
            {
                //如果当前位置小于最小值,则更新最小值
                if (arr[j].compareTo(arr[min]) < 0)
                    min = j;
                //否则就继续迭代下一个位置
            }
            //每一趟结束找到最小值后,将最小值与未排序的第一个元素做交换
            swap(arr, i,min);

            //以下两步不是必须,此处打印只是为了结果能清楚的观察
            System.out.println("第"+(i+1)+"趟排序后的数组为:");
            System.out.println(Arrays.toString(arr));
        }

    }

}
import java.util.Arrays;

public class SortTest {
    public static void main(String[] args) {
        Integer[] arr = new Integer[]{3, 9, -1, 10, -2};
        System.out.println("未排序前的数组为:");
        System.out.println(Arrays.toString(arr));
        SelectionSort selectionSort = new SelectionSort();
        selectionSort.sort(arr);
    }
}

1.4 性能分析

  • 运行时间与输入无关,即与输入的数组是否排序无关
  • 选择排序的数据移动是最少的,每次交换都会改变两个数组元素的值,因此选择排序用了n-1次交换,交换次数和数组的大小是线性关系,其他任何算法都不具备这个特征
  • 遍历次数:n-1(n为数组长度)
  • 比较次数:
  • 交换次数:n-1

优化前的冒泡排序和选择排序性能测试代码:

public class SortPerformanceTest {
    public static void main(String[] args) {
        //创建100000个随机数据
        Double[] arr1 = new Double[100000];
        for (int i = 0; i < arr1.length; i++) {
            arr1[i] = (Double) (Math.random() * 10000000);  //这里使用10000000是为了让数据更分散
        }

        //赋值上述创建的数组arr1的值到数组arr2
        Double[] arr2 = new Double[100000];
        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = arr1[i];
        }

        //创建两种排序类的对象
        BubbleSort bubbleSort = new BubbleSort();
        SelectionSort selectionSort = new SelectionSort();

        //使用优化前的冒泡排序对arr1进行排序
        long bubbleSort_start = System.currentTimeMillis();
        bubbleSort.sort(arr1);
        long bubbleSort_end = System.currentTimeMillis();

        System.out.println("优化前的冒泡排序所用的时间为:"+(bubbleSort_end - bubbleSort_start)+"ms");

        //使用选择排序对arr2进行排序
        long selectionSort_start = System.currentTimeMillis();
        selectionSort.sort(arr2);
        long selectionSort_end = System.currentTimeMillis();

        System
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值