插入排序——折半插入排序

1.基本概念

折半插入排序是将待排序序列分成两部分,前边是已经排好序的有序序列,后面是无序序列。每次从无序序列中拿出一个待排序元素a[i],按照折半查找的思想找到应插入位置a[high+1],折半查找是要找到这个元素,而插入排序是应该找到比前一个元素大,同时又比后一个元素小的位置。

2.函数实现

/*
算法思想:将待排序队列看成两部分,前半部分有序,后半部分无序。起始状态下,第一个元素有序,后面全部无序。
每次取出无序队列中的一个元素,将其插入有序队列。
对有序队列折半查找,找到待插入数据在有序队列中的位置。
进行插入操作。
*/
int HalfInsertSort(int a[],int n){
    int low,mid,high;
    int temp;
    for(int i=1;i<n;i++){
        if(a[i-1]>a[i]){//保证了排序的稳定性
            temp=a[i];
            low=0;
            high=i-1;
            //寻找插入位置
            for(int j=i-1;j>=0&&low<=high;j--){
                mid=(low+high)/2;
                if(a[mid]<temp)
                    low=mid+1;
                else{
                    high=mid-1;
                }
            }

        for(int k=i-1;k>high;k--)
            a[k+1]=a[k];
        a[high+1]=temp;
        }

    }
    for(int m=0;m<n;m++)
        printf("%d\t",a[m]);
    printf("折半插入排序!!!\n");
    return 1;
}

3.主函数

int main()
{
    int a[]={10,1,5,40,52,2,4};
    int n=sizeof(a)/sizeof(int);
    //DirectInsertSort(a,n);
    HalfInsertSort(a,n);
    return 0;
}

4.完整代码

#include <iostream>

using namespace std;

//直接插入排序
//DirectInsertSort(int &a[]);
//折半插入排序
//HalfInsertSort(int &a[]);
//希尔排序
//ShellInsertSort(int &a[]);


void DirectInsertSort(int a[],int n){
    //int i=0;
    int j=0;
    int temp;
    int k;

    //根据数组性质,第一个元素a[0]本身有序,排序从第二个元素开始
    for(j=1;j<n;j++){
        temp=a[j];
        if(j>0&&a[j-1]>a[j]){
            for(k=j;k>0&& a[k-1]>temp;k--){
                a[k]=a[k-1];
            }
            a[k]=temp;
        }

    }
    for(j=0;j<n;j++)
        printf("%d\t",a[j]);
    printf("直接插入排序!!!\n");
}

/*
算法思想:将待排序队列看成两部分,前半部分有序,后半部分无序。起始状态下,第一个元素有序,后面全部无序。
每次取出无序队列中的一个元素,将其插入有序队列。
对有序队列折半查找,找到待插入数据在有序队列中的位置。
进行插入操作。
*/
int HalfInsertSort(int a[],int n){
    int low,mid,high;
    int temp;
    for(int i=1;i<n;i++){
        if(a[i-1]>a[i]){//保证了排序的稳定性
            temp=a[i];
            low=0;
            high=i-1;
            //寻找插入位置
            for(int j=i-1;j>=0&&low<=high;j--){
                mid=(low+high)/2;
                if(a[mid]<temp)
                    low=mid+1;
                else{
                    high=mid-1;
                }
            }

        for(int k=i-1;k>high;k--)
            a[k+1]=a[k];
        a[high+1]=temp;
        }

    }
    for(int m=0;m<n;m++)
        printf("%d\t",a[m]);
    printf("折半插入排序!!!\n");
    return 1;
}




int main()
{
    int a[]={10,1,5,40,52,2,4};
    int n=sizeof(a)/sizeof(int);
    //DirectInsertSort(a,n);
    HalfInsertSort(a,n);
    return 0;
}

5.运行过程(手动操作)

6.运行结果

7.总结

在写折半插入排序的时候if语句里面的for循环我写出来过,感觉自己懂了折半插入排序,但是又不理解为什么待排序元素要插在a[high+1],自己手动走了前两个插入过程,大致知道它不满足low<=high时退出循环high小于low,这样他应该插入到a[high+1]的位置,也就是a[low]位置。当遇到感觉自己已经会了的时候,但运行报错或者写不出来,就再看一遍算法定义,可以手动模拟一下过程,就会有一个不一样的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值