zoukankan      html  css  js  c++  java
  • 渐增型算法二:合并两个有序序列

    一、问题描述

    /*

    • descrition:合并两个有序序列A[p...q]和A[q+1...r]
    • input:序列指针a,元素大小size,有序序列下标p、q、r,比较函数cmp
    • output:a整体排序,成功返回0
      */

    二、方法一:逐个比较两个序列数据

    static int mergeTwoListV1(void *array, int size, int head, int middle, int tail,int(*cmp)(void *, void *))
    {
        int i = 0;
        int j = 0;
        int k = head;
        int len1 = middle - head + 1;
        int len2 = tail - middle; 
        // 子序列内存申请,并初始化
        void *firstArray = (void*)malloc(len1 * size);
        void *secondArray = (void*)malloc(len2 * size);
        memcpy(firstArray, array + head * size, len1 * size);
        memcpy(secondArray, array + (middle + 1) * size, len2 * size);
        while (i < len1 && j < len2) {
            if (cmp(firstArray + i * size, secondArray + j *size) > 0) {
                // 将firstArray中的元素覆盖array
                memcpy(array + k * size, firstArray + i *size, size);
                k++;
                i++;
            } else {
                // 将secondArray中的元素覆盖array
                memcpy(array +k * size, secondArray + j * size, size);
                k++;
                j++;
            }
        }
        // firstArray数组有剩余元素
        if (i < len1) {
            memcpy(array + k * size, firstArray + i * size, (len1 - i) * size);
        }
        // secondArray数组有剩余元素
        if (j < len2) {
            memcpy(array + k * size, secondArray + j * size, (len2 - j) * size);
        }
        // 以上两个if条件,最多只有一个成立
        free(firstArray);
        free(secondArray);
        return 0;
    }
    

    三、方法二:将一个序列数据依次插入另外一个已排序序列

    原地排序,子序列A[p...q]不动,依次取A[q+1...r],将其插入之前的已经排序好的序列中,类似插入排序方法

    static int mergeTwoListV2(void *array, int size, int head, int middle, int tail,int(*cmp)(void *, void *))
    {   
        // 将A[q+1...r]逐个添加到有序的A[p...q]中, 参考插入排序过程
        void *key = (void*)malloc(size);
        memset(key, 0, size);
        int j;
        for (int i = middle + 1; i < tail + 1; i++) {
            key = memcpy(key, array + i * size, size);
            j = i - 1;
            while (j >= 0 && cmp(array + j * size, key) < 0) {
                memcpy(array + (j + 1) * size, array + j * size, size);
                j--;
            }
            memcpy(array + (j + 1) * size, key, size);
            printfList("mergeTwoListV2 test: ", (int*)array, ARREY_LEN);
        }
        return 0;
    }
    

    四、测试

    测试代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define ARREY_LEN 10
    
    static void printfList(char *info, int *array, int len)
    {
        printf("%s", info);
        for(int i = 0; i < len; i++) {
            printf("%d ", array[i]);
        }
        printf("
    ");
        return;
    }
    
    int intGreater(void *x, void *y)
    {
        return *(int *)x - *(int *)y;
    }
    
    // 合并函数实现
    
    int main(void)
    {
        int array[ARREY_LEN] = {1, 2, 5, 8, 9, 0, 3, 4, 7, 6};
        int ret;
        printfList("list before merge: ", array, ARREY_LEN);
        //ret = mergeTwoListV1(array, sizeof(int), 0, 4, 9, intGreater);
        ret = mergeTwoListV2(array, sizeof(int), 0, 4, 9, intGreater);
        if (ret != 0) {
            printf ("merge list faile.
    ");
        }
        printfList("list after merge: ", array, ARREY_LEN);
        while (1);
        return 0;
    }
    

    测试结果:
    方法一:

    方法二:

  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1036. Boys vs Girls (25)
    1035 Password (20)
    1027 Colors in Mars (20)
    1009. Product of Polynomials (25)
    1006. Sign In and Sign Out
    1005 Spell It Right (20)
    1046 Shortest Distance (20)
    ViewPager页面滑动,滑动到最后一页,再往后滑动则执行一个事件
    IIS7.0上传文件限制的解决方法
  • 原文地址:https://www.cnblogs.com/HZL2017/p/14318585.html
Copyright © 2011-2022 走看看