数据结构与算法——插入排序

还是先上算法视频讲解:浙大——数据结构与算法(插入排序)

1. 算法实现

先给个视频,直观感受一下插入排序的逻辑。

InsertSort.wmv

插入排序作为简单排序的一种,可能是每个人天生就会的算法(谁还没打过扑克牌呢?),就想打扑克整牌的时候,将最小的牌一般会放在手中最左边,一手牌就是个升序排序的过程。直接贴算法:

//插入排序算法,升序算法
void insertSort(int* arr,int num){
    int i,j;
    for(i=1;i<num;i++){//从位置1开始,到数组的最后
        int tmp=arr[i];//先保存i位置的元素
        for(j=i;j>0&&arr[j-1]>tmp;j--)//如果j-1(j初始为i)位置的元素大于tmp
            arr[j]=arr[j-1];    //此时应该将j-1位置的元素后移,第一次移动后,arr[i-1]挪到了arr[i]的位置
        arr[j]=tmp;//上面for循环结束后,说明arr[j-1]小于tmp了,此时arr[j]应该是tmp的合适位置
    }
}

带上创建随机数数组,验证算法并输入输出的完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//宏定义
#define MAX 1000
#define MIN 0
#define ARRAYLEN 10
//函数声明
int* generateArray(int num);
void InsertSort(int* arr,int num);
void displayArray(int* arr,int num);

int main(void){
    //生成随机的int数组
    int* array=generateArray(ARRAYLEN);
    printf("Raw data:\n");
    displayArray(array,ARRAYLEN);
    //插入排序
    InsertSort(array,ARRAYLEN);
    printf("Sorted data:\n");
    displayArray(array,ARRAYLEN);

    return 0;
}
//插入排序算法,升序算法
void InsertSort(int* arr,int num){
    int i,j;
    for(i=1;i<num;i++){//从位置1开始,到数组的最后
        int tmp=arr[i];//先保存i位置的元素
        for(j=i;j>0&&arr[j-1]>tmp;j--)//如果j-1(j初始为i)位置的元素大于tmp
            arr[j]=arr[j-1];    //此时应该将j-1位置的元素后移,第一次移动后,arr[i-1]挪到了arr[i]的位置
        arr[j]=tmp;//上面for循环结束后,说明arr[j-1]大于tmp了,此时arr[j]应该是tmp的合适位置
    }
}
//生成MAX和MIN范围内的包含num个元素的数组
int* generateArray(int num){
    srand((unsigned)time(NULL));
    int* arr=(int*)malloc(sizeof(int)*num);
    for(int i=0;i<num;i++)
        arr[i]=((MAX-MIN+1)*rand()/(RAND_MAX+1.0)+MIN);
    return arr;
}
//打印数组
void displayArray(int* arr,int num){
    for(int i=0;i<num;i++)
        printf("%d ",arr[i]);
    printf("\n");
}

2. 使用函数指针构造通用的插入排序算法

通过用户构造比较函数,实现一个通用的插入排序算法,通过不同的比较函数定义,完成升序或者降序排序。

插入排序算法:

//函数声明,p是一个函数指针,指向用户定义的比较函数
void InsertSort(int* arr,int num,int (*p)(int*,int*));
//函数实现:插入排序算法,通用算法
void InsertSort(int* arr,int num,int (*p)(int*,int*)){
    int i,j;
    for(i=1;i<num;i++){//从位置1开始,到数组的最后
        int tmp=arr[i];//先保存i位置的元素
        for(j=i;j>0&&(*p)(&arr[j-1],&tmp)>0;j--)//根据p指向的比较函数,决定插入排序是升序还是降序
            arr[j]=arr[j-1];    
        arr[j]=tmp;//上面for循环结束后,arr[j]应该是tmp的合适位置
    }
}

用户定义的比较函数示例:

//函数声明
int Ascend(int* a,int* b);  //升序排序时使用的比较函数
int Descend(int* a,int* b); //降序排序时使用的比较函数
//函数定义
//升序排序时使用的比较函数
int Ascend(int* a,int* b){
    return (*a)-(*b);
}
//降序排序时使用的比较函数
int Descend(int* a,int* b){
    return (*b)-(*a);
} 

到这里可能会想到C语言标准库自带的qsort函数,上面使用函数指针调用外部自定义的比较函数来决定排序的是升序还是降序,思路就来源于C标准库的qsort函数。快排序实在太经典了,C标准库封装了这个函数,除了能实现数字类型的排序,还可以实现字符串排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值