简体   繁体   English

C-为什么该程序打印两个0?

[英]C - Why is this program printing two 0's?

Here is the program. 这是程序。 It takes a hardcoded set of integers and sorts them from least to greatest. 它采用一组硬编码的整数并将其从最小到最大排序。 I copied it from a book and I can't for the life of my decipher how it does what it does so maybe someone can help me understand. 我从一本书中复制了它,但我无法一辈子破译它是如何工作的,因此也许有人可以帮助我理解。

MAIN 主要

/* Test merge() and mergesort(). */

#include "mergesort.h"

int main(void) {
    int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};

    sz = sizeof(key) / sizeof(int);
    printf("Before mergesort:");
    wrt(key, sz);
    mergesort(key, sz);
    printf("After mergesort:");
    wrt(key, sz);
    return 0;
}

MERGE.C MERGE.C

/* Merge a[] of size m and b[] of size n into c[]. */
#include "mergesort.h"
void merge(int a[], int b[], int c[], int m, int n)
{
    int i = 0, j = 0, k = 0;

    while (i < m && j < n)
        if (a[i] < b[j])
            c[k++] = a[i++];
        else
            c[k++] = b[j++];
    while (i < m)   /* pick up an remainder */
        c[k++] = a[i++];
    while (j < n)
        c[k++] = b[j++];
}

MERGESORT.C MERGESORT.C

/* Mergesort: Use merge() to sort an array of size n. */

#include "mergesort.h"
void mergesort(int key[], int n) // n is 0 to begin with
{
    int j,k,m, *w;
    int x,y;

    for (m = 1; m < n; m *= 2)      /*m is a power of 2*/
        if (n < m){
            printf("ERROR: Array size not a power of 2 - bye!\n");
            exit(1);
        }

    w = calloc(m, sizeof(int));     /* allocate workspace */
    assert(w != NULL);             /* check that calloc() worked */
    for (k = 1; k < n; k *= 2) {
        for (j = 0; j < n - k; j += 2 * k)
            /*
              Merge two subarrays of key[] into a subarray of w[].
            */
            merge(key + j, key + j + k, w + j, k, k); // todo: make the two k's not equal
        for (j = 0; j < n; ++j)
            key[j] = w[j];
    }


    free(w);
}

MERGESORT.H MERGESORT.H

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
void merge(int a[], int b[], int c[], int m, int n);
void mergesort(int key[], int n);
void wrt(int key[] , int sz);

WRT.C WRT.C

#include "mergesort.h"

void wrt(int key[], int sz)
{
    int i;

    for (i = 0; i < sz; ++i)
        printf("%4d%s", key[i], ((i < sz - 1) ? "" : "\n"));
}

When it's printed out, there are two zeroes. 打印出来时,有两个零。 How is this happening? 这是怎么回事? I think the secret to this lies in mergesort.c, with the k value. 我认为这的秘密在于具有k值的mergesort.c。 As you can see near the bottom, I commented in "todo: make the two k's not equal", this is the simplified solution my teacher offered for me. 正如您在底部附近看到的那样,我在“待办事项:使两个k不相等”中评论,这是老师为我提供的简化解决方案。 I also put in the x and y ints which will be the separate k values. 我还输入了x和y整数,这将是单独的k值。 But I don't understand, how can I split this one value into two? 但是我不明白,如何将这个值一分为二?

The problem is in this part of code of function mergesort() : 问题出在函数mergesort()这部分代码中:

    for (m = 1; m < n; m *= 2)      /*m is a power of 2*/
    if (n < m){
        printf("ERROR: Array size not a power of 2 - bye!\n");
        exit(1);
    }

This is supposed to check whether the size of the array, to be sort, is having the size in power of 2 and the size of the array you are passing is 13 (not the power of 2 ): 这应该检查要排序的数组的大小是否具有2幂,并且您要传递的数组的大小是否为13 (不是2的幂):

int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};

it should throw error and exit but since the power of 2 check is incorrect it proceeds further and your merge sort code is not capable of sorting an array of uneven size . 它应该抛出错误并退出,但是由于power of 2校验的power of 2是不正确的,它会继续进行并且您的合并排序代码无法排序大小不一的数组 Hence, you are getting the incorrect output for the array of uneven size. 因此,对于大小不均的数组,您得到的输出不正确。

In the for loop for循环中

for (m = 1; m < n; m *= 2) 
            ^^^^^

the loop will iterate till m < n and the in the loop body if condition you are checking if要检查条件,则循环将迭代直到m < n和循环体中的

if (n < m){ ....

which will never happen because as soon as m > n the loop will exit. 这将永远不会发生,因为一旦m > n ,循环就会退出。

Instead of checking the power of 2 , I believe you want to check whether the size of the array is even or not. 相信您无需检查2的幂,而是要检查数组的大小是否even To check whether the size is even or not you can simply do: 要检查大小是否均匀 ,您可以执行以下操作:

   if (n & 1)
   {
       printf("ERROR: Array size not a multiple of 2 - bye!\n");
       exit(1);
   }

For sorting an array using merge sort, it's not required that the size of the array should be even . 为了使用合并排序对数组进行排序,不需要数组的大小应为偶数 You can use merge sort to sort an array of odd size as well. 您也可以使用合并排序对奇数大小的数组进行排序。 Check this answer . 检查此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM