当前位置: 首页 > 知识库问答 >
问题:

当我使用合并排序时,为什么要将额外的元素添加到我的val**数组中?

郎长卿
2023-03-14

当我使用mergeSort对我的val**数组进行排序时(此数组包含指向整数的val*指针),一个额外的1(一个新元素)似乎被添加到数组中。我几乎可以肯定问题出在mergeSortmer中,因为在调用mergeSort之前打印我的val**数组时,数据是正确的(只是未排序)。这是代码。

#define SIZE 10

void mergeSort(void**, int, int);
void merge(void**, int, int, int);
int compare(void*, void*);

int main(void) {
    int array[SIZE] = { 5, 6, 3, 2, 5, 6, 7, 4, 9, 3 };
    void *voidArray[SIZE];
    int query = 1;
    void *queryPointer = &query;

    for (int j = 0; j < SIZE; j++) {
        voidArray[j] = &array[j];
    }

    printArray(voidArray);
    mergeSort(voidArray, 0, SIZE);
    printArray(voidArray);
    result = binarySearch(voidArray, 0, SIZE, queryPointer);

    if (result == -1) {
        puts("Query not found.");
        return(0);
    }

    printf("Query found at index %d.\n", result);
    return(0);
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void mergeSort(void **array, int head, int tail) {
    if (head < tail) {
        int middle = (head + ((tail - head) / 2));
        mergeSort(array, head, middle);
        mergeSort(array, (middle + 1), tail);
        merge(array, head, middle, tail);
    }
}

void merge(void **array, int head, int middle, int tail) {
    int headLength = (middle - head + 1);
    int tailLength =  (tail - middle);
    void *headSide[headLength];
    void *tailSide[tailLength];

    for (int i = 0; i < headLength; i++) {
        headSide[i] = array[head + i];
    }

    for (int j = 0; j < tailLength; j++) {
        tailSide[j] = array[middle + 1 + j];
    }

    int k = head;
    int l = 0;
    int m = 0;
    while (l < headLength && m < tailLength) {
        if (compare(headSide[l], tailSide[m]) == -1) {
            array[k] = headSide[l];
            l++;      
        } else {  
            array[k] = tailSide[m];
            m++;
        }
        k++;
    }

    while (l < headLength) {
        array[k] = headSide[l];
        l++;
        k++;
    }

    while (m < tailLength) {
        array[k] = tailSide[m];
        m++;
        k++;
    }
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int compare(void *index, void *query) {
    if (*((int *)index) == *((int *)query)) {
        return (0);
    }

    if (*((int*)index) > *((int*)query)) {
        return (1);        
    }

    return (-1);
}

输出应该包含未排序的数组、已排序的数组,以及是否找到了查询。未排序的数组中没有1,但排序后的数组中有一个1;此外,排序结果中缺少编号9(有趣的是,如果我对9执行二进制搜索,它会告诉我9位于索引10)。

输出示例(用于查询1):

5 6 3 2 5 6 7 4 9 3
1 2 3 3 4 5 5 6 6 7

在index0处找到查询。

共有3个答案

闾丘博超
2023-03-14

margeSortmerge的参数有些混乱。传递范围中最后一个元素的索引在C中并不惯用。在范围结束后传递元素的索引要简单得多,这与传递0SIZEintmain()合并排序(voidArray,0,SIZE) 结果=二进制搜索(voidArray,0,SIZE,queryPointer)

以下是使用此API的修改版本:

void mergeSort(void **array, int head, int tail) {
    if (tail - head > 1) {
        int middle = head + (tail - head) / 2);
        mergeSort(array, head, middle);
        mergeSort(array, middle, tail);
        merge(array, head, middle, tail);
    }
}

void merge(void **array, int head, int middle, int tail) {
    int headLength = middle - head;
    int tailLength = tail - middle;
    void *headSide[headLength];
    void *tailSide[tailLength];

    for (int i = 0; i < headLength; i++) {
        headSide[i] = array[head + i];
    }
    for (int j = 0; j < tailLength; j++) {
        tailSide[j] = array[middle + j];
    }

    int k = head;
    int l = 0;
    int m = 0;
    while (l < headLength && m < tailLength) {
        if (compare(headSide[l], tailSide[m]) <= 0) {
            array[k++] = headSide[l++];
        } else {  
            array[k++] = tailSide[m++];
        }
    }
    while (l < headLength) {
        array[k++] = headSide[l++];
    }
    while (m < tailLength) {
        array[k++] = tailSide[m++];
    }
}

但是请注意,使用自动存储(也称为堆栈上)分配临时数组HeadSidetinSide对于大型数组来说是有风险的。此外,没有必要将右半部分的元素保存到tinSide中,因为它们在复制到最终位置之前不会被覆盖。这是合并的简单版本:

void merge(void **array, int head, int middle, int tail) {
    int headLength = middle - head;
    void *headSide[headLength];

    for (int i = 0; i < headLength; i++) {
        headSide[i] = array[head + i];
    }

    int k = head;
    int l = 0;
    while (l < headLength && middle < tail) {
        if (compare(headSide[l], array[middle]) <= 0) {
            array[k++] = headSide[l++];
        } else {  
            array[k++] = array[middle++];
        }
    }
    while (l < headLength) {
        array[k++] = headSide[l++];
    }
}

张坚白
2023-03-14
headSide[i] = array[head + i];

headSide[i]isvoidarray[head i]isvoid*

倪振海
2023-03-14

检查数组下标。

int tailLength =  (tail - middle)

tail是数组的大小,我认为tailLength是不正确的。

 类似资料:
  • 问题内容: 我正在尝试使用排序字符串数组。这是我的代码: 现在的输出是: 我得到的是结果,但不是我想得到的结果,它们是: 如何调整代码以正确地对字符串数组进行排序? 问题答案: 你的输出是正确的。开头用“ Hello”和“ This”的白色字符表示。 另一个问题是你的方法。使用方法: 输出: 这里数组“ is”的第三个元素应该是“ Is”,否则它将在排序后排在最后。因为sort方法在内部使用ASC

  • 我有下面的数据帧模式作为df.current模式,需要获得预期的模式作为df.expected模式,有没有一种方法,我可以在火花2.3实现这一点 df.current架构: df。预期架构: 示例数据: 注意:这里需要实现两件事: 为元素中的每个E、V对创建新字段SN,其值应为数组名称。例如:对于第一个数组列(ADA),SN的值=ADA 将阵列(ADA、ADW)合并为一个外部阵列(信号)

  • 我一直在试着分析mergesort,但我被一个奇怪的错误击中了。这是我的代码: 我一直在使用典型的合并排序代码。我在理解为什么需要将内容从临时数组复制到主数组以获得正确的输出时遇到了问题。我尝试了以下输入:5(术语数量), 4 2 我得到的输出为:3 2 4 4 5,而没有将内容从临时数组复制到主数组,如果我使用“注释”循环进行复制,输出很好,即2 3 4 4 5。我只是不明白,为什么会这样?

  • 问题内容: AJAX通话: 我收到以下错误:。但是,当我使用Postman时,我只需要添加带有url 的标头即可返回字符串。 请给我一些帮助,以解决问题。 我的目标是允许原始服务器以及正确提供的API密钥从Web Api取回数据。 问题答案: 在请求中添加标头会触发您的浏览器首先发送CORS预检OPTIONS请求。除了定义为CORS安全列出的请求标头的标头之外,添加到请求中的 任何 标头都将触发您

  • 问题内容: 我对git和詹金斯都很陌生。 我将密钥添加到bitbucket和本地计算机中时: 我可以克隆。 但是,当我将相同的url()添加到Jenkins存储库url时,出现以下错误: 问题答案: 您还需要为Jenkins用户设置ssh密钥。 通常的想法是,您登录到Jenkins框,并成为“ jenkins”用户。您可以为您的Jenkins用户打电话,所以请确保使用正确的名称。一旦成为Jenki

  • 我只是在学习静态编程语言的早期阶段,所以我播放了一段视频,展示了许多常见的静态编程语言习语:静态编程语言教程 就在视频的1:03:10点,演示者讨论了可变集合和不可变集合。正如您在视频中看到的,他创建了一个带有var关键字的可变列表和一个带有val关键字的不可变列表。我很好奇,如果我尝试将val与可变列表一起使用,会发生什么错误;我认为这是不允许的,这个想法会显示一条这样的信息,但它没有给我错误信