我遇到以下VS 2010代码的问题。我试图对一组结构进行排序。代码编译没有错误,速度非常快,但是存在排序结果不正确的问题。
我按“zip”字符串排序(出于测试目的,不是数字,而是通过字符比较)。我有一个使用标准的lib qsort运行的版本,但想要做一些进一步的摆弄,所以我自己编写。
struct address {
char name[40];
char street[40];
char city[20];
char state[30];
char zip[21];
};
void qs_struct(struct address items[], int left, int right)
{
int i, j;
char *x;
struct address temp;
i = left;
j = right;
x = items[(left+right)/2].zip;
do {
while((strcmp(items[i].zip,x) < 0) && (i < right)){ i++;}
while((strcmp(items[j].zip,x) > 0) && (j > left)) { j--;}
if(i <= j) {
temp = items[i];
items[i] = items[j];
items[j] = temp;
i++; j--;
}
} while(i <= j);
if(left < j) qs_struct(items, left, j);
if(i < right) qs_struct(items, i, right);
}
void qx(struct address items[], int count)
{
qs_struct(items,0,count-1);
}
void fillStructWithRandomDataForTest(struct address *addr, int i, int j)
{
char temp[444];
sprintf(temp, "%d%d", j +i, j*i);
strcpy(addr->name, temp);
sprintf(temp, "%d%d", j +i, j*i);
strcpy(addr->street, temp);
sprintf(temp, "%d%d", j +i, j*i);
strcpy(addr->city, temp);
sprintf(temp, "%d%d", j +i, j*i);
strcpy(addr->state, temp);
sprintf(temp, "%d%d", j +i, j*i);
strcpy(addr->zip, temp);
}
void xqs(void)
{
struct address addrs[20];
for (int i = 0, j = 33; i < 16; ++i, --j)
fillStructWithRandomDataForTest(&addrs[i], i, j);
qx(addrs, 16);
// results: incorrectly sorted
for (int k = 0; k < 16; ++k)
printf("%s \n",addrs[k].zip);
}
答案 0 :(得分:2)
如果你告诉我们你的结果究竟是什么方式不正确会很好,但是没关系,让我猜一下:它什么都不打印,对吧?所有空行,是吗?
代码中的最后一个循环使用k
作为循环计数器,但随后它使用i
作为索引来选择printf()
的结构。这将始终选择尚未初始化的addrs[16]
。
你需要咖啡。或睡觉。但不是两个。
答案 1 :(得分:1)
此
x = items[(left+right)/2].zip;
将枢轴绑定到某个位置。移动中间地址时,与拉链比较的枢轴会发生变化。这搞砸了那种。您需要复制要比较的zip,
x = strdup(items[(left+right)/2].zip); // or strlen and malloc
while (...)
free(x);
答案 2 :(得分:0)
而不是:
while((i < n) && (strcmp(list[i].name, key) < 0)) i++;
while((j > m) && (strcmp(list[j].name , key) > 0)) j--;
应该是这样的:
while((i <= n) && (strcmp(list[i].name, key) <= 0)) i++;
while((j >= m) && (strcmp(list[j].name , key) > 0)) j--;