zoukankan      html  css  js  c++  java
  • 数据结构 排序(归并排序)

    //归并排序--递归算法的运用
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<time.h>
    
    /*
    归并排序步骤:
    第一步;将一组数据分成2部分,然后递归的继续将这2部分数据划分成4部分,直接每个部分只剩下一个元素
    第二步:对相邻2组之间的数据进行归并
    */
    
    //打印数组
    void Print(int * arr, int num){
        if (arr == NULL)
        {
            printf("传入参数不可以为空!
    ");
            return;
        }
        int i = 0;
        for (int i = 0; i < num; i++)
        {
            printf("%5d", *(arr + i));
        }
        printf("
    ");
    }
    
    //归并排序--两组之间合并
    /*
    src:第一个小数组的地址
    srct:第二个小数组的地址
    dec:归并后结果的数组地址
    len1:第一个数组的长度
    len2:第二个数组的长度
    */
    static void Merge(int * dec, int *src, int *srct, int len1, int len2)
    {
        int i = 0, m = 0, n = 0;
        while (m < len1&&n < len2)
        {
            //比较必须两组都有值,所以需要"m<len1 && n<len2"条件
            if (src[m]<srct[n])
            {
                dec[i++] = src[m++];
            }
            else
            {
                dec[i++] = srct[n++];
            }
        }
        //若还剩几个尾部元素  依次插入
        while (m < len1)
        {
            dec[i++] = src[m++];
        }
        while (n < len2)
        {
            dec[i++] = srct[n++];
        }
    }
    
    //递归分组算法
    /*
    @arr:既做输入,又做输出
    */
    static void MSort(int *arr, int len)
    {
        //当数组元素为1,,说明只剩下一个元素
        if (len==1)
        {
            return;
        }
        //两个分组的长度
        int len1 = 0,len2=0;
        //根据数组长度的奇偶性,确定被拆分数组的长度
        int flag = len % 2 == 0 ? 0 : 1;
        if (flag==0)
        {
            len1 = len2 = len/2;
        }
        else
        {
            len1 = len / 2;
            len2 = len / 2+1;
        }
        //分配拆分数组的内存空间
        int *temparr1 = (int *)malloc(sizeof(int)*len1);
        if (temparr1==NULL)
        {
            printf("malloc() failed 
    ");
            return;
        }
        memset(temparr1, 0, sizeof(int)*len1);
        int *temparr2 = (int *)malloc(sizeof(int)*len2);
        if (temparr2 == NULL)
        {
            printf("malloc() failed 
    ");
            return;
        }
        memset(temparr2, 0, sizeof(int)*len2);
        //数据拆分
        int i = 0,m=0,n=0;
        for (i = 0; i < len; i++)
        {
            if (i<len1)
            {
                temparr1[m++] = arr[i];
            }
            else
            {
                temparr2[n++] = arr[i];
            }
        }
        //递归分组
        MSort(temparr1, len1);
        MSort(temparr2, len2);
        //组合数据
        Merge(arr, temparr1, temparr2, len1, len2);
        //释放内存
        free(temparr1);
        free(temparr2);
    }
    
    void Test(){
        int i = 0;
        int arr[10] = { 0 };
        //定义时间类型变量
        time_t ts;
        //生成随机数种子
        srand((unsigned int)time(&ts));
        for (i = 0; i < 10; i++)
        {
            arr[i] = (int)(rand() % 100);
        }
        //打印数组
        printf("
    原始数据----
    ");
        Print(arr, 10);
        MSort(arr, 10);
        Print(arr, 10);
    }
    
    void main(){
        Test();
        system("pause");
    }
    //排序--归并排序法
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<time.h>
    
    /*
    归并排序步骤:
    第一步;将一组数据分成2部分,然后递归的继续将这2部分数据划分成4部分,直接每个部分只剩下一个数组
    第二步:对相邻2组之间的数据进行归并
    */
    
    //打印数组
    void Print(int * arr, int num){
        if (arr == NULL)
        {
            printf("传入参数不可以为空!
    ");
            return;
        }
        int i = 0;
        for (int i = 0; i < num; i++)
        {
            printf("%5d", *(arr + i));
        }
        printf("
    ");
    }
    
    //归并排序--两组之间合并
    /*
    src:第一个小数组的地址
    srct:第二个小数组的地址
    dec:归并后结果的数组地址
    len1:第一个数组的长度
    len2:第二个数组的长度
    */
    void Merge(int * src, int *srct, int *dec, int len1, int len2){
        int i = 0, j = 0,k=0;
        //注意 这里使用的是“&&”  因为只需要一个数组插入完成  另一个数组依次插入返回数组后面即可
        while (i <len1 && j <len2){
            if (src[i]<srct[j])
            {
                dec[k++] = src[i++];
            }
            else{
                dec[k++] = srct[j++];
            }
        }
        //若还剩几个尾部元素  依次插入
        while (i < len1){
            dec[k++] = src[i++];
        }
        //若还剩几个尾部元素  依次插入
        while (j < len2){
            dec[k++] = srct[j++];
        }
    }
    
    //归并排序--分组
    void MSort(int * src,int *dec,int low,int high){
        if (low == high)
        {
            //说明只有一个元素  不用排序了  直接把原始数据 放置到新数组中
            dec[0] = src[low];
            return;
        }
        //将原始数组元素一分为二
        //注意   将数组分割成2部分   中间元素的下标是 (high+low) / 2   不是 (high-low) / 2
        //假设 下标是3,和下标5  中间的下标应该是4
        int mid = (high+low) / 2;
        //第一组的长度
        int m = mid - low + 1;
        //第二组的长度
        int n = high - (mid + 1) + 1;
        /*
        开辟两个数组空间  分别存放被分开的2组元素
        */
        int * space = (int *)malloc(sizeof(int)*m);
        if (space==NULL)
        {
            printf("开辟内存空间失败!
    ");
            return;
        }
        //初始化
        memset(space, 0, sizeof(int)*m);
        int * spacet = (int *)malloc(sizeof(int)*n);
        if (spacet == NULL)
        {
            printf("开辟内存空间失败!
    ");
            return;
        }
        //初始化
        memset(spacet, 0, sizeof(int)*n);
        //递归调用   直至将数组元素变成1个为止
        MSort(src, space,low, mid);
        MSort(src, spacet, mid + 1, high);
        //归并排序   dec是由上一层函数分配的内存
        Merge(space, spacet, dec, m, n);
        free(space);
        free(spacet);
    }
    
    void Test(){
        int i = 0;
        int arr[10] = { 0 };
        int relt[10] = { 0 };
        //定义时间类型变量
        time_t ts;
        //生成随机数种子
        srand((unsigned int)time(&ts));
        for (i = 0; i < 10; i++)
        {
            arr[i] = (int)(rand() % 100);
        }
        //打印数组
        printf("
    原始数据----
    ");
        Print(arr, 10);
        //归并法排序
        printf("归并法排序之后的数据
    ");
        /*
          这里作为返回的数组,为什么可以传本身呢?
          因为归并的数据都是放在临时创建的内存空间里,并没有破坏原来的数据  
          最后一次归并 是将临时内存空间里的数据覆盖了原来的内存空间
          0是数组的最小下标
          9是数组的最大下标
        */
        MSort(arr, arr, 0, 9);
        Print(arr, 10);
    }
    
    void main(){
        Test();
        system("pause");
    }

  • 相关阅读:
    python的三元运算符
    百度站长社区有价值SEO问题提炼(一)
    Python文件夹与文件的操作
    python核心编程课后题第二版第十章264页
    python核心编程课后题第二版第九章230页
    python核心编程课后题第二版第八章209页
    《python核心编程》课后题第二版第十一章308页
    PhoneGap源码分析1——说明
    EF db first 获取表名称
    SQL Server使用证书最小粒度授权
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5749082.html
Copyright © 2011-2022 走看看