插入类排序----直接插入排序

一、基本思想

将第i个记录的关键字Ki,与前面的r[1]~r[i-1]个记录元素比较,将关键字大于Ki的 记录向后移一个位置,知道遇见关键字小于 Ki 的记录,该位置既为r[i]插入的位置。

在这里要注意,比较时,i为要比较记录的下标,则从 i-1 开始比,即和她之前的比。

r[0]用作监视哨;

二、具体例子

比如  关键字为 33  12   24   48    33   68      利用直接插入排序进行排序的具体过程如下:

      初始状态                r[0]            r[1]               r[2]                 r[3]               r[4 ]                  r[5]                r[6]

                                                         33                12                  24                 48                  33                 68

                                                                        待插入记录


      第一趟                   12              12                 33                   24                48                  33                  68

                                                              有序序列                      待插入


     第二趟                    24              12                 24                  33                  48                 33                  68


     第三趟                    48               12               24                   33                 48                  33                  68                    注意看这趟比较是否多余


    第四趟                    33               12                24                 33                    33                  48                68


    第五趟                    68              12                 24                 33                    33                  48                68                    注意这趟是否也多余


这里呢。r[0]作为监视哨的作用有两个   :

1. 防止数组越界

2.存备查记录

三、核心代码

先写一下没有优化的代码

void insertSort(RecordList L)
{
    for(i = 2;i <= L.length;i++ )
    {
         L.r[0] = L.r[i];
         for(j = i-1;L.r[j].key >  L.r[0].key;i++)   //大于才用移
	{
		L.r[j+1] = L.r[j];
	}
	L.r[j+1] = L.r[0];                  //插入到正确位置
    }
}


刚才在举例子的时候,发现第三趟、第五趟,其实可以不用进行该趟排序,为什么他们不需要排序,因为 r[i]   > r[i-1]  ,也就是说,它已经大于前面排好序的最大数,所以它不用跑这一趟,不许再和前面的比较。下面是优化的代码

void insertSort(RecordList L)
{

    for(i = 2;i <= L.length;i++ )
    {
        if(L.r[i].key < L.r[i-1].key )
	{
           L.r[0] = L.r[i];
           for(j = i-1;L.r[j].key >  L.r[0].key;i++)   //大于才用移
	   {
		L.r[j+1] = L.r[j];
	   }
	   L.r[j+1] = L.r[0];                  //插入到正确位置
        }
    }
}

其实上面就是多加了一个 if判断,看这一趟需不需要再比较。

插入排序是稳定的,因为它需要一个元素空间作为辅助空间r[0] 做交换,所以空间复杂度为 O(1)   

它适用于顺序存储结构,即数组,也适用于链式存储结构,在链式存储结构上,它不需要移动位置,而是修改相应的指针。

完整java代码:

package analyse;

public  class Test{
        public static void main(String[] args) {
        int a[] = {33,12,25,46,33,68,19,80};
        Test t = new Test();
        a = t.f(a);
        t.print(a);
    }
    private  void print(int[] a) {
        for(int i = 0;i < a.length;i++){
            System.out.print("  "+ a[i]);
        }
    }
    private int[] f(int a[]) {
        int temp,j;
        for(int i = 1;i<a.length;i++){
            temp = a[i];
            for(j = i-1;j > -1 && temp < a[j];j--){
                a[j + 1] = a[j];
            }
            a[j+1] = temp;
        }
        return a;
        
    }
}






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值