[英]C - Why is this program printing two 0's?
這是程序。 它采用一組硬編碼的整數並將其從最小到最大排序。 我從一本書中復制了它,但我無法一輩子破譯它是如何工作的,因此也許有人可以幫助我理解。
主要
/* 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 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: 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
#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
#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"));
}
打印出來時,有兩個零。 這是怎么回事? 我認為這的秘密在於具有k值的mergesort.c。 正如您在底部附近看到的那樣,我在“待辦事項:使兩個k不相等”中評論,這是老師為我提供的簡化解決方案。 我還輸入了x和y整數,這將是單獨的k值。 但是我不明白,如何將這個值一分為二?
問題出在函數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);
}
這應該檢查要排序的數組的大小是否具有2
冪,並且您要傳遞的數組的大小是否為13
(不是2
的冪):
int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};
它應該拋出錯誤並退出,但是由於power of 2
校驗的power of 2
是不正確的,它會繼續進行並且您的合並排序代碼無法排序大小不一的數組 。 因此,對於大小不均的數組,您得到的輸出不正確。
在for
循環中
for (m = 1; m < n; m *= 2)
^^^^^
if
要檢查條件,則循環將迭代直到m < n
和循環體中的
if (n < m){ ....
這將永遠不會發生,因為一旦m > n
,循環就會退出。
相信您無需檢查2
的冪,而是要檢查數組的大小是否even
。 要檢查大小是否均勻 ,您可以執行以下操作:
if (n & 1)
{
printf("ERROR: Array size not a multiple of 2 - bye!\n");
exit(1);
}
為了使用合並排序對數組進行排序,不需要數組的大小應為偶數 。 您也可以使用合並排序對奇數大小的數組進行排序。 檢查此答案 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.