【数据结构—排序】折半插入排序

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define MaxSize 50

//折半插入排序 是针对 在 整个顺序表 或 数组的"有序区"里 用'二分查找法'
//先查找到 待插入元素A[i]应该插入的位置,然后再移动比A[i]大的元素,最后插入A[i]

//所以这里的"折半",是对数组 或 顺序表 "有序区" 的折半,而不是对整个数组的折半.
//!! A[i]最后插入的位置一定是A[low]或者A[high+1]; (这里low = high +1)

void BinaryInsertSort(int A[],int n){
    int i,j,low,high,mid;

    //这个大的for循环作用: 提供需要排序的元素(从A[2]~A[n-1]) (时间复杂度:O(n))
    for(i = 2;i < n;i++){    //这里i从2开始,那是因为A[1]是默认排好了的
        A[0] = A[i];             //将要排序的元素先放在A[0]里
        low = 1;
        high = i-1;
        //下面要开始找目前A[0]中的元素 所 应该排的位置
        //用二分查找法查找
        while(low<=high){  //本轮循环作用:找A[0]应该插入的位置 (时间复杂度:O(log2n))
            mid = (low + high)/2;    //注意,这个'时间复杂度'是"比较"!!
            if(A[0] < A[mid])
                high = mid - 1;
            else
                low = mid + 1;
        }        //这一轮循环结束时,(如果没有重复元素,必定是查找失败的)
                 //这时low > high 且 low = high + 1;
                 //因为二分查找的区间是顺序表,所以low所指的元素>A[0]>high所指的元素
                 //因此这轮的A[0]最后会被插在A[low]的位置中(或者说A[high + 1])
        
        for(j = i-1;j <= low;j--){        //本轮循环作用: 移动元素
            A[j+1] = A[j];                    //这轮循环的时间复杂度:O(n)
        }                                //注意!这个'时间复杂度'是"移动元素"!!
        A[low] = A[0];        //插入
    }
}


//总结:由于一共有三个循环:1.for循环  2.while循环(用于查找)  3. for循环(用于移动)
//所以'折半插入排序' 查找的次数 约为:O(1.for) * O(2.while) = O(nlog2n) 
//(!!但这只是查找)

//这种方法 元素移动的次数并未改变,仍 依赖于 待排序表 的初始状态
//所以,折半插入排序 的 时间复杂度 仍为 O(1.for) * O(3.for) = O(n^2).

//是一种稳定的排序方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值