数据结构与算法-排序算法3-插入排序

目录

1.插入排序:

1.介绍:

2.动态图解

3.举例

4.小结插入排序规则

5.插入排序代码

6.运行时间

代码:

运行结果:


1.排序算法简介

排序也称为排序算法。排序是将一组数据依据指定的顺序进行排列的过程。

2.常见的排序算法分类如下图:

稳定性口诀:

选泡插,快归堆希桶计基,不稳稳稳不稳稳,不稳不稳稳稳稳

3.插入排序:

1.介绍:

数组中n个元素,把这n个待排序元素看成一个有序序列和一个无序序列。开始时有序序列中只有一个元素,无序序列中有n-1个元素。排序过程中每次从无序序列中取出第一个元素,把它与有序序列中元素进行比较,将它插入到有序序列中的适当位置。这样有序序列中就多了一个元素,无序序列中就少了一个元素。直到无序序列中没有元素了,整个数组中元素就排好序了。

插入排序是将无序序列中元素一个个插入到有序序列中。

2.动态图解

3.举例

比如原始数组为:(17),3,25,14,20,9

第一次插入:(3,17),25,14,20,9 因为初始时17作为有序序列中的元素,3作为无序序列中的第一个元素,就把3和17比较,3更小,插入到17前面

第二次插入:(3,17,25),14,20,9 将25和(3,17)比较,在3和17之间,所以插入到中间

第三次插入:(3,14,17,25),20,9 将14和(3,17,25)比较,在3和17之间,所以插入到中间

第四次插入:(3,14,17,20,25),9 将20和(3,14,17,25)比较,在17和25之间,所以插入到中间

第五次插入:(3,9,14,17,20,25) 将9和(3,14,17,20,25)比较,在3和14之间,所以插入到中间

因为假设第一个数据是有序的,所以只需要对后面的n-1个元素进行插入。

4.小结插入排序规则

①数组元素个数为n,就一共进行n-1次插入

②每一趟插入都是先记下待插入的值,待插入数的前一个下标。在循环中找比待插入数大的数的下标,没找到就让已经比较过的有序序列中的数往后移,这个下标往前移,找到的下标就是待插入的前一个位置。所以待插入的数下标就是这个移动下标的后一个,也就是+1。

5.插入排序代码

包括推导代码和最终代码

    public static void insertSort1(int[] arr) {
        //第一轮
        //定义待插入的数
        int insertVal = arr[1];//先保存
        int insertIndex = 1 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第一轮插入:" + Arrays.toString(arr));
        //第二轮
        //定义待插入的数
        insertVal = arr[2];//先保存
        insertIndex = 2 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第二轮插入:" + Arrays.toString(arr));
        //第三轮
        //定义待插入的数
        insertVal = arr[3];//先保存
        insertIndex = 3 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第三轮插入:" + Arrays.toString(arr));
        //第四轮
        //定义待插入的数
        insertVal = arr[4];//先保存
        insertIndex = 4 - 1;//待插入数的前面一个下标
        //找到insetVal的位置
        //为了保证插入位置不越界,且待插入数还没有找到插入位置
        //就将arr[insertIndex]后移,也就是把位置让出来
        while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            insertIndex--;
        }
        //退出循环时就已经找到插入位置,想想什么时候退出循环?
        // insertVal>=arr[insertIndex],值比找到的下标对应的值大了,那么值应该在的位置是不是在找到的下标后面。
        // insertIndex+1这个下标才是真正的待插入位置,把前面保存的待插入的数的值赋给这个下标
        arr[insertIndex + 1] = insertVal;
        System.out.println("第四轮插入:" + Arrays.toString(arr));
        //发现输出和推的一样,就推四轮
        /*
        第一轮插入:[3, 17, 25, 14, 20, 9]
        第二轮插入:[3, 17, 25, 14, 20, 9]
        第三轮插入:[3, 14, 17, 25, 20, 9]
        第四轮插入:[3, 14, 17, 20, 25, 9]
         */
    }

    //归纳找到规律后就用两层循环写
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }
            arr[insertIndex + 1] = insertVal;
            System.out.println("第" + i + "轮插入:" + Arrays.toString(arr));
        }
    }
}

运行结果:

6.运行时间

插入段记录时间的代码。排序前记一次时间,排序后记一次时间。

然后输出元素的代码就先注释掉。

代码:

package com.xjj.sort;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class InsertSort {
    public static void main(String[] args) {
//        int[] arr = {17, 3, 25, 14, 20, 9};
//        insertSort(arr);
        int arr2[]=new int[80000];
        for(int i=0;i<80000;i++){
            arr2[i]=(int)(Math.random()*80000);
        }
        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间为:"+date1Str);
        insertSort(arr2);
        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间为:"+date2Str);
    }

    //归纳找到规律后就用两层循环写
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int insertVal = arr[i];
            int insertIndex = i - 1;
            while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }
            arr[insertIndex + 1] = insertVal;
//            System.out.println("第" + i + "轮插入:" + Arrays.toString(arr));
        }
    }
}

运行结果:

80000个元素,选择排序运行时间1秒。


插入排序是将无序序列中元素一个个插入到有序序列中


后面会继续写希尔排序等排序算法的内容。分类排序部分写完之后再给出一些题目练习^_^加油加油

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值