C语言排序方法-----二分插入排序

       由于在直接插入排序过程中,待插入数据左边的序列总是有序的,针对有序序列,就可以用二分法去插入数据了,也就是二分入排序法。适用于数据量比较大的情况。

    二分插入排序的算法思想是:
(1)计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;
(2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 .......快速的确定出第 i 个元素要插在什么地方;
(3)确定位置之后,将整个序列后移,并将元素插入到相应位置。

下面看C代码的实现

void insertSortBinary( int num[], int count )
{
    int i, j;
    for( i = 1; i < count; i++ )
    {
        if( num[i] < num[i - 1] )
        {
            int temp = num[i];
            int left = 0, right = i - 1;
            while( left <= right )
            {
                int mid = ( left + right ) / 2;
                if( num[mid] < temp )
                {
                    left = mid + 1;
                }
                else
                {
                    right = mid - 1;
                }
            }
            //只是比较次数变少了,交换次数还是一样的
            for( j = i; j > left; j-- )
            {
                num[j] = num[j - 1];
            }
            num[left] = temp;
        }
    }
}

        用left和right两个变量来标记数组中已经排好序的数字范围。left默认为排好数的最左边,right默认为排好数的最右边。取出需要排序的数字和已经排好序的数字中间的数字比较,如果待排序的数比排好序中间的数字小,说明带排序的数要插入已经排好序的前半部分,这时候将right移动到排好序中间位置的前一位,这样需要比较的次数就减少了一半,下来继续用待排序的数和排好序的数字前一半数的中间值继续比较,也就是和整体排好序的1/4位置数字比较,如果带排序的数比1/4处的数字大,就将left变量移动到1/4数字的后面,这时候left的位置就在1/4处的后一位,right的位置就在1/2处的前一位。下来继续将待排序的数和left与right位置中间的数比较,不断地缩小left和right变量的范围,直到right位置跑到了left的右边,说明需要插入的位置已经确定了,就是left变量所标记的位置。这时候先把left右边的数据统一向右移动一位,然后将待排序的数字插入到left当前位置,此时一趟排序就完成了。

下面看一下执行过程:

insertSortBinary test
原始数组:0 8 1 5 4 3 7 9 2 6
left=0,right=1,mid=0,tem=1
 mid 0 < temp 1   右移left
left=1,right=1,tem=1
left=1,right=1,mid=1,tem=1
 mid 8 > temp 1   左移right
left=1,right=0,tem=1
整体右移: 0 8 8 5 4 3 7 9 2 6
第  1趟 : 0 1 8 5 4 3 7 9 2 6
left=0,right=2,mid=1,tem=5
 mid 1 < temp 5   右移left
left=2,right=2,tem=5
left=2,right=2,mid=2,tem=5
 mid 8 > temp 5   左移right
left=2,right=1,tem=5
整体右移: 0 1 8 8 4 3 7 9 2 6
第  2趟 : 0 1 5 8 4 3 7 9 2 6
left=0,right=3,mid=1,tem=4
 mid 1 < temp 4   右移left
left=2,right=3,tem=4
left=2,right=3,mid=2,tem=4
 mid 5 > temp 4   左移right
left=2,right=1,tem=4
整体右移: 0 1 5 8 8 3 7 9 2 6
整体右移: 0 1 5 5 8 3 7 9 2 6
第  3趟 : 0 1 4 5 8 3 7 9 2 6
left=0,right=4,mid=2,tem=3
 mid 4 > temp 3   左移right
left=0,right=1,tem=3
left=0,right=1,mid=0,tem=3
 mid 0 < temp 3   右移left
left=1,right=1,tem=3
left=1,right=1,mid=1,tem=3
 mid 1 < temp 3   右移left
left=2,right=1,tem=3
整体右移: 0 1 4 5 8 8 7 9 2 6
整体右移: 0 1 4 5 5 8 7 9 2 6
整体右移: 0 1 4 4 5 8 7 9 2 6
第  4趟 : 0 1 3 4 5 8 7 9 2 6
left=0,right=5,mid=2,tem=7
 mid 3 < temp 7   右移left
left=3,right=5,tem=7
left=3,right=5,mid=4,tem=7
 mid 5 < temp 7   右移left
left=5,right=5,tem=7
left=5,right=5,mid=5,tem=7
 mid 8 > temp 7   左移right
left=5,right=4,tem=7
整体右移: 0 1 3 4 5 8 8 9 2 6
第  5趟 : 0 1 3 4 5 7 8 9 2 6
left=0,right=7,mid=3,tem=2
 mid 4 > temp 2   左移right
left=0,right=2,tem=2
left=0,right=2,mid=1,tem=2
 mid 1 < temp 2   右移left
left=2,right=2,tem=2
left=2,right=2,mid=2,tem=2
 mid 3 > temp 2   左移right
left=2,right=1,tem=2
整体右移: 0 1 3 4 5 7 8 9 9 6
整体右移: 0 1 3 4 5 7 8 8 9 6
整体右移: 0 1 3 4 5 7 7 8 9 6
整体右移: 0 1 3 4 5 5 7 8 9 6
整体右移: 0 1 3 4 4 5 7 8 9 6
整体右移: 0 1 3 3 4 5 7 8 9 6
第  6趟 : 0 1 2 3 4 5 7 8 9 6
left=0,right=8,mid=4,tem=6
 mid 4 < temp 6   右移left
left=5,right=8,tem=6
left=5,right=8,mid=6,tem=6
 mid 7 > temp 6   左移right
left=5,right=5,tem=6
left=5,right=5,mid=5,tem=6
 mid 5 < temp 6   右移left
left=6,right=5,tem=6
整体右移: 0 1 2 3 4 5 7 8 9 9
整体右移: 0 1 2 3 4 5 7 8 8 9
整体右移: 0 1 2 3 4 5 7 7 8 9
第  7趟 : 0 1 2 3 4 5 6 7 8 9
共执行了7次!
 

下面看一下若数组中的数排序是最坏情况下排序需要多少趟

insertSortBinary test
原始数组:9 8 7 6 5 4 3 2 1 0
left=0,right=0,mid=0,tem=8
 mid 9 > temp 8   左移right
left=0,right=-1,tem=8
整体右移: 9 9 7 6 5 4 3 2 1 0
第  1趟 : 8 9 7 6 5 4 3 2 1 0
left=0,right=1,mid=0,tem=7
 mid 8 > temp 7   左移right
left=0,right=-1,tem=7
整体右移: 8 9 9 6 5 4 3 2 1 0
整体右移: 8 8 9 6 5 4 3 2 1 0
第  2趟 : 7 8 9 6 5 4 3 2 1 0
left=0,right=2,mid=1,tem=6
 mid 8 > temp 6   左移right
left=0,right=0,tem=6
left=0,right=0,mid=0,tem=6
 mid 7 > temp 6   左移right
left=0,right=-1,tem=6
整体右移: 7 8 9 9 5 4 3 2 1 0
整体右移: 7 8 8 9 5 4 3 2 1 0
整体右移: 7 7 8 9 5 4 3 2 1 0
第  3趟 : 6 7 8 9 5 4 3 2 1 0
left=0,right=3,mid=1,tem=5
 mid 7 > temp 5   左移right
left=0,right=0,tem=5
left=0,right=0,mid=0,tem=5
 mid 6 > temp 5   左移right
left=0,right=-1,tem=5
整体右移: 6 7 8 9 9 4 3 2 1 0
整体右移: 6 7 8 8 9 4 3 2 1 0
整体右移: 6 7 7 8 9 4 3 2 1 0
整体右移: 6 6 7 8 9 4 3 2 1 0
第  4趟 : 5 6 7 8 9 4 3 2 1 0
left=0,right=4,mid=2,tem=4
 mid 7 > temp 4   左移right
left=0,right=1,tem=4
left=0,right=1,mid=0,tem=4
 mid 5 > temp 4   左移right
left=0,right=-1,tem=4
整体右移: 5 6 7 8 9 9 3 2 1 0
整体右移: 5 6 7 8 8 9 3 2 1 0
整体右移: 5 6 7 7 8 9 3 2 1 0
整体右移: 5 6 6 7 8 9 3 2 1 0
整体右移: 5 5 6 7 8 9 3 2 1 0
第  5趟 : 4 5 6 7 8 9 3 2 1 0
left=0,right=5,mid=2,tem=3
 mid 6 > temp 3   左移right
left=0,right=1,tem=3
left=0,right=1,mid=0,tem=3
 mid 4 > temp 3   左移right
left=0,right=-1,tem=3
整体右移: 4 5 6 7 8 9 9 2 1 0
整体右移: 4 5 6 7 8 8 9 2 1 0
整体右移: 4 5 6 7 7 8 9 2 1 0
整体右移: 4 5 6 6 7 8 9 2 1 0
整体右移: 4 5 5 6 7 8 9 2 1 0
整体右移: 4 4 5 6 7 8 9 2 1 0
第  6趟 : 3 4 5 6 7 8 9 2 1 0
left=0,right=6,mid=3,tem=2
 mid 6 > temp 2   左移right
left=0,right=2,tem=2
left=0,right=2,mid=1,tem=2
 mid 4 > temp 2   左移right
left=0,right=0,tem=2
left=0,right=0,mid=0,tem=2
 mid 3 > temp 2   左移right
left=0,right=-1,tem=2
整体右移: 3 4 5 6 7 8 9 9 1 0
整体右移: 3 4 5 6 7 8 8 9 1 0
整体右移: 3 4 5 6 7 7 8 9 1 0
整体右移: 3 4 5 6 6 7 8 9 1 0
整体右移: 3 4 5 5 6 7 8 9 1 0
整体右移: 3 4 4 5 6 7 8 9 1 0
整体右移: 3 3 4 5 6 7 8 9 1 0
第  7趟 : 2 3 4 5 6 7 8 9 1 0
left=0,right=7,mid=3,tem=1
 mid 5 > temp 1   左移right
left=0,right=2,tem=1
left=0,right=2,mid=1,tem=1
 mid 3 > temp 1   左移right
left=0,right=0,tem=1
left=0,right=0,mid=0,tem=1
 mid 2 > temp 1   左移right
left=0,right=-1,tem=1
整体右移: 2 3 4 5 6 7 8 9 9 0
整体右移: 2 3 4 5 6 7 8 8 9 0
整体右移: 2 3 4 5 6 7 7 8 9 0
整体右移: 2 3 4 5 6 6 7 8 9 0
整体右移: 2 3 4 5 5 6 7 8 9 0
整体右移: 2 3 4 4 5 6 7 8 9 0
整体右移: 2 3 3 4 5 6 7 8 9 0
整体右移: 2 2 3 4 5 6 7 8 9 0
第  8趟 : 1 2 3 4 5 6 7 8 9 0
left=0,right=8,mid=4,tem=0
 mid 5 > temp 0   左移right
left=0,right=3,tem=0
left=0,right=3,mid=1,tem=0
 mid 2 > temp 0   左移right
left=0,right=0,tem=0
left=0,right=0,mid=0,tem=0
 mid 1 > temp 0   左移right
left=0,right=-1,tem=0
整体右移: 1 2 3 4 5 6 7 8 9 9
整体右移: 1 2 3 4 5 6 7 8 8 9
整体右移: 1 2 3 4 5 6 7 7 8 9
整体右移: 1 2 3 4 5 6 6 7 8 9
整体右移: 1 2 3 4 5 5 6 7 8 9
整体右移: 1 2 3 4 4 5 6 7 8 9
整体右移: 1 2 3 3 4 5 6 7 8 9
整体右移: 1 2 2 3 4 5 6 7 8 9
整体右移: 1 1 2 3 4 5 6 7 8 9
第  9趟 : 0 1 2 3 4 5 6 7 8 9
共执行了9次!
 

在看一一下最好情况下需要多少趟

insertSortBinary test
原始数组:0 1 2 3 4 5 6 7 8 9
共执行了0次!
最好情况下一趟也不需要执行。

下面在测试一下随机生成10000个数据排序需要的次数和时间

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值