问题描述
#include<stdio.h>
#include<string.h>
int main()
{
setbuf(stdout,NULL);
char str1[50][50],temp[50];
int lim,i,j,res;
printf("Enter the number of strings: ");
scanf("%d",&lim);
for(i=0;i<lim;i++)
{
scanf("%s",str1[i]);
}
for(i=0;i<lim;i++)
{
for(j=1;j<lim-1;j++)
{
res=strcmp(str1[i],str1[j]);
if(res==1)
{
strcpy(temp,str1[i]);
strcpy(str1[i],str1[j]);
strcpy(str1[j],temp);
}
}
}
for(i=0;i<lim;i++)
{
puts(str1[i]);
}
return 0;
}
我正在尝试使用冒泡排序对用户输入的字符串进行排序。但是结果并不能正确显示。
if
语句中的逻辑有错误吗?
解决方法
正如@ h0r53在评论中观察到的那样,您实现的内容根本不是冒泡排序。它几乎是一个选择排序,但是它具有错误的内循环迭代界限,这似乎使人联想起冒泡排序。组合已损坏。从选择排序的角度来看,这是错误的,因为您从不考虑最后一个元素,并且效率很低,因为您不必要地重新考虑已经排序的线索元素。
算法正确的选择排序版本的关键部分可能看起来像这样:
for (i = 0; i < lim; i++) {
for (j = i + 1; j < lim; j++) { // These bounds are changed vs. the original
// Compare each subsequent element with element i:
res = strcmp(str1[i],str1[j]);
if (res > 0) {
strcpy(temp,str1[i]);
strcpy(str1[i],str1[j]);
strcpy(str1[j],temp);
}
}
}
或者,这将是算法上正确的Bubble Sort版本:
// for (i = 0; i < lim; i++) { // particularly inefficient; note: no i in the loop body
for (; lim > 1; lim--) {
for (j = 0; j < lim - 1; j++) { // Almost,but not quite,the same as the original
// Compare each element but the last with the following one:
res = strcmp(str1[j],str1[j + 1]);
if (res > 0) {
strcpy(temp,str1[j + 1]);
strcpy(str1[j + 1],temp);
}
}
}
此实现在每次外循环迭代时将lim
减少1,因为每次迭代都会使最大元素中的下一个冒泡至其正确的最终位置,在此无需再次考虑。
如果您按以下方式更改排序语句,则您的代码可以运行: 发件人:
for(i=0;i<lim;i++)
{
for(j=1;j<lim-1;j++)
{
res=strcmp(str1[i],str1[j]);
if(res==1)
{
strcpy(temp,temp);
}
}
}
到
while (cont) {
cont = 0;
for (int i = 0; i < lim - 1; i++)
{
res=strcmp(str1[i],str1[i+1]);
if (res > 0)
{
strcpy(temp,str1[i+1]);
strcpy(str1[i+1],temp);
cont = 1;
}
}
}