插入排序

一、定义

1.1 说明

图解:
1328967-20190411230324954-392020146.png

描述:

​ 对N个元素的数组进行插入排序,它将有N-1次排序完成。其原理也很简单:从第二个元素开始对每一个元素进行排序,即p=1开始,对每一位置p上的元素与前0到p上的元素对比,将p放入合适的位置。所以第p趟排序时,位置p前面的元素已经排序好了。只需要将p上的元素插入到一个已经排序的合适的位置。

做法:将p上的元素向左移动到x,直到位置x-1的元素比它小,x+1上的元素比它大。

例如数组a[]={34,8,64,51,32,21}。我们从p=1开始进行排序,将a[p]元素左移,直到它在合适的位置。

p=1时,对8进行排序:8,34,64,51,32,21;

p=2时,对64进行排序:8,34,64,51,32,21;

p=3时,对51进行排序:8,34,51,64,32,21;

p=4时,对32进行排序:8,32,34,51,64,21;

p=5时,对21进行排序:8,21,32,34,51,64;

1.2 算法分析

很明显,根据前面的描述,定义p为索引位置,当p=1时,最多需要用到1次比较,p=2时,最多需要2次比较。一直到p=N-1。所以总的比较次数最多:
\[ \sum_{i=2}^{N}i=1+3+···+(N-1)=\Theta(N^2) \]

由于插入排序的性质:将p放入前面已经排序的数组片段中。所以,输入几乎被排序的数组,插入排序会运行得很快。

Java代码

/**
 * 插入排序
 *
 * @Author: dhcao
 * @Version: 1.0
 */
public class InsertionSortEx<T extends Comparable<? super T>> {

    /**
     * 直接对数组a进行排序
     *
     * @param a   需要排序数组
     * @param <T> 实现Comparable接口对类型
     */
    public static <T extends Comparable<? super T>> void insertionSort1(T[] a) {

        // 技巧1:在循环中重复定义的函数,可以放到循环外定义。
        int j;

        /**
         * 从位置p=1开始,对所有对数组元素进行排序
         */
        for (int p = 1; p < a.length; p++) {

            // 提前将排序的元素a[p]准备好
            T tmp = a[p];

            // 将位置p上的元素向左边移动(即p左边的元素向右移动)(由于左边从0到p-1的元素已经在排序状态)
            for (j = p; j > 0 && tmp.compareTo(a[j - 1]) < 0; j--) {
                
                // 技巧2:将必须的操作留在循环中,不需要的操作可以移到循环外
                a[j] = a[j - 1];
            }
            a[j] = tmp;
        }

    }

    /**
     * 将数组中的某一段进行排序。
     * @param a 数组
     * @param left 需要排序的左界
     * @param right 需要排序的右界
     * @param <T> 实现Comparable接口对类型
     */
    public static <T extends Comparable<? super T>> void insertionSort2(T[] a,int left,int right){
        
        int j;
        for (int p = left + 1; p <= right; p++) {
            T tmp = a[p];
            for (j = p; j > 0 && tmp.compareTo(a[j - 1]) < 0; j--) {
                a[j] = a[j - 1];
            }
            a[j] = tmp;
        }
    }

}

转载于:https://www.cnblogs.com/dhcao/p/10693286.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值