排序算法-插入排序

//直接插入排序
/*
插入排序的思想彻底理清楚了,代码实现起来就非常简单了
基本思想:就像打扑克一样,将提取的每个元素不断的插入到已经排好序的数组中。
思想很简单,但是要实现代码,还需要将整个过程描述一遍。
1、首先第一个元素是排好序的,不用再排序,那就从第二个元素开始。
2、假设前面的n个元素是排好序的,那么接下来应该将第n+1个元素放到合适的位置,如何放呢:
                                *首先将该元素作为关键字,并把它原来的位置空下来。
                                *将前面的元素不断跟关键字比较,只要比关键字大就要向后移动一位,这样空位置就不断往前移动
                                *当遇到比关键字小的元素或移动到头部,停止移动
                                *将该关键字放到空位置
*/
void InsertSort(int list[],int size)
{
    for(int i=1;i<size;i++)//将后面的size-1个元素不断排序
    {
        int key=list[i];//将要排序的元素作为关键字。
        int j=i-1;//j用来记录前边要比较的元素的序号
        for(;j>=0&&list[j]>key;j--)//移动的条件
            list[j+1]=list[j];//移动
        list[j+1]=key;//当移动停止时,将关键字放到正确的位置
    }
}
//

//直接插入搞明白了,希尔排序就非常简单了,希尔排序是插入排序的一种改善。
/*直接插入排序在将每个元素进行排序时需要移动比它大的所有元素,希尔排序则采用
分组的形式,分组形式采用等间隔方式,比如如果间隔为2,则1,3,5是一组,2,4,6是一组,然后对每组
采用直接插入排序方式,然后采用小间隔重复,直到间隔为1,当间隔为1时相当于对所有进行排序
*/
//希尔排序
void myShellSort(int list[],int size)
{
    int gap=size/2;
    while(gap>=1)
    {
        for(int i=0;i<gap;i++)//对所有组进行排序
        {
            for(int j=i+gap;j<size;j+=gap)//对每组进行排序
            {
                int key=list[j];
                int k=j-gap;
                for(;k>=0&&list[k]>key;k-=gap)//对元素的移动
                    list[k+gap]=list[k];
                list[k+gap]=key;
            }
        }
        gap/=2;//间隔不断缩小,直到为0停止
    }
}

//仔细分析,可以将希尔排序的代码改善如下:
void shellSort(int list[],int size)
{
    int gap = size / 2;
    while (1 <= gap) {
        // 把距离为 gap 的元素编为一个组,扫描所有组
        for (int i = gap; i < size; i++) {
            int j = 0;
            int temp = list[i];
            // 对距离为 gap 的元素组进行排序
            for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap) {
                list[j + gap] = list[j];
            }
            list[j + gap] = temp;
        }
         gap = gap / 2; // 减小增量
    }
}

//使用折半搜索改进的插入排序
/*
希尔排序对插入排序的改进是通过减少移动次数,我们都知道,移动元素所花费的代价大于比较花费的代价
而采用折半搜索改进的是减少比较的次数。在直接插入排序中,每当将一个元素放到正确的排序位置时,都需要
与前边的排好序的数组进行比较,我们可以通过折半查找来减少比较次数
*/
/*
折半查找的思想很简单,就是在有序数组中,先与中间的元素比较,大的话在右边查找,小的话在左边查找,相等则找到,因此终止条件为相等或区间内没有元素
而对于插入排序来说,应该是要找到关键元素要插入的位置,因此终止条件应该为中间没有元素,可问题又来了,当中间没有元素时,应选用上界作为要插入的位置还是
下界呢,可以分析一下。在本次递归之前应该是index1==index2,即他们指向同一个元素,而key如果小于这个元素,则该元素的位置为index1,而如果大于等于这个元素
则位置为index2。而当key小于这个元素时,应该将该元素后移,即key插入到index1位置,当key大于等于这个元素,key应该保持原来的位置不变,而key应该插入到index2+1的位置,而此时index2+1==index1,因此返回index1,综上可述,应该返回index1
*/
int seekInsertPlace(int list[],int index1,int index2,int key)
{
    if(index1>index2)
    {
        if(list[index1]>=key)
            return index1;
        else if(list[index1]<key)
            return index1+1;
    }
    int index=(index1+index2)/2;
    if(list[index]>key)
        return seekInsertPlace(list,index1,index-1,key);
    else
        return seekInsertPlace(list,index+1,index2,key);
}


//使用折半搜索改进的插入排序
void binaryInsertSort(int list[],int size)
{
    for(int i=1;i<size;i++)//将后面的size-1个元素依次排序
    {
        int key=list[i];//将要排序的元素作为关键字。
        int insertIndex=seekInsertPlace(list,0,i-1,key);//寻找要插入的位置
        for(int j=i-1;j>=insertIndex;j--)//移动的条件
            list[j+1]=list[j];//移动
        list[insertIndex]=key;//当移动停止时,将关键字放到正确的位置
    }
}



//另外对于这几种插入排序算法的分析可参看http://www.cnblogs.com/heyuquan/p/insert-sort.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值