插入排序

     插入排序的基本思想:每次将一个待排序的记录插入按照关键字的大小插入到前面已排序的子序列中,直到全部记录插入完成为止。

比较常用的两种插入排序算法是直接插入排序希尔排序。下面分别介绍两种排序算法的基本思想、具体实现、复杂度分析。

一.直接插入排序

   1.基本思想

             直接插入排序假定将整个待排序序列分为两个部分:已排序子序列与待排序子序列。

            对于待排序序列S[1....n],可以分为两个子序列,S1[1...i]代表已排序子序列(排序开始时只有第一个元素),S2[i+1...n]代表待排序子序列。在每次排序过程中从S2中获取一个元素插入到S1序列中正确的位置,直到S2序列中所有的元素被正确插入到S1中。

   2.算法描述

             假定序列S是一个含有n个可排序元素的序列,i为待排序子序列下标,j为已排序子序列下标,temp为临时变量。

             (1).排序开始,令i从1递增到n-1,重复(2)、(3)、(4)。

             (2).单次插入排序排序开始,将Si保存到temp中。

             (3).确定插入位置。

             (4).右移已排序序列中从插入位置到该序列最后一个元素的位置。

             (5).将temp插入到插入位置,单次插入排序完成。

             (6).排序完成。

    3.具体实现

               只考虑增序情况, 给出java实现如下:

public static void insertionSort(int[] array){
        int len = array.length;
        int i,j,temp;
        for(i = 1;i < len;i++){
              //将待插入元素保存至临时变量
              temp = array[i];
              j = i - 1;
              //确定正确的插入位置
               while(j >= 0 && temp < array[j]){
                     array[j+1] = array[j];
                     j--;
              }
              //将待插入元素插入到正确的位置
              array[j+1] = temp;
        }
}

      4.算法分析

                      (1).时间复杂度分析

                                最好情况,序列已排序,即n次循环内部的while的condition语句中判定为false,时间复杂度为O(n)。

                                平均情况,时间复杂度为O(n^2)。

                               最坏情况,序列为反序,即n此循环内部的while的condition语句中判定为true,时间复杂度为O(n^2)。

                     (2).空间复杂度分析

                               只定义了一个临时变量,所以空间复杂度为O(1)


二.希尔排序

      1.基本思想

                  希尔排序也叫缩减增量排序,通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着排序的进行而减小,直到只比较相邻元素的最后一趟排序为止。

                  希尔排序与直接插入排序在比较元素的上的差别是:希尔排序比较的是相距一定间隔的元素,而直接插入排序比较的是待插入元素与每一个已排序序列中的元素。

      2.算法描述

                         假定S={s1...sn}为一个含有n个可排序元素的待排序序列,i为待排序子序列的下标,j为已排序子序列的下标,temp为临时变量,gap为距离变量。

                       (1).排序开始,初始化距离变量gap,重复(2),(3),(4)。

                       (2).确定待排序序列中的元素范围gap~n。

                       (3).单次插入排序开始,将当前待插入元素赋值给temp。

                       (4).通过比较temp与已排序序列(j~gap)中的元素确定正确的插入位置并交换符合条件的相距gap的已排序元素。

                       (5).插入元素,单次插入排序结束。

                       (6).排序结束。

      3.具体实现       

                         只考虑增序情况,并选择流行的增量序列为len/2,java代码如下:  

public static void shellSort(int[] array) {
		int len = array.length;
		int j, temp;
		//选定增量,直到gap<0即比较的是相邻元素时结束
		for (int gap = len / 2; gap > 0; gap /= 2) {
			//循环待插入序列
			for (int i = gap; i < len; i++) {
				temp = array[i];
				//移动已排序序列,确定插入位置
				for (j = i; j >= gap && temp < array[j - gap]; j -= gap) {
					array[j] = array[j - gap];
				}
				//插入元素
				array[j] = temp;
			}
		}
}

           4.算法分析

                              (1).时间复杂度

                                        希尔排序的执行时间依赖于增量序列的选择,但最坏的情况依然是O(n^2)。

                              (2).空间复杂度

                                       与直接插入排序的空间复杂度相同,都是O(1)。

总结:插入排序的效率依赖于比较次数与移动次数,当待排序序列已排序度较大时,插入排序效率较高,甚至比快速排序效率还要高,而希尔排序通过比较一定距离的元素使得每次排序的比较与移动次数减少,并且随着排序的进行,序列的已排序度越来越高,又降低了比较与移动的次数,这也是为什么希尔排序在时间性能上优于直接插入排序的原因。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值