问题出现:
请先看一段为了完成对10个整数从小到大排序的代码:
#include <stdio.h>//选择排序法排序
int main()
{
int a[10],i,j,temp,min;
for(i=0;i<=9;i++)
{
printf("a[%d]:",i);
scanf("%d",&a[i]);//输入10个待排序的整数
}
printf("\n");
printf("The original numbers:\n");
for(i=0;i<=9;i++)
{
printf("%5d",a[i]);
}
printf("\n");
for(i=0;i<=9;i++)
{
min=i;//记录初始需要换位置的数列元素下标
for(j=i+1;j<=9;j++)
{
if(a[i]>a[j])//按照从小到大的顺序排列(出问题的地方!!)
{
i=j;//更新比较数据元素,同时记录最后一个待换数据元素的下标
}
}
temp=a[min];
a[min]=a[i];
a[i]=temp;//将第i+1个数据交换为此i+1轮遍历后的最小数
}
printf("The sorted numbers:\n");
for(i=0;i<=9;i++)
{
printf("%5d",a[i]);//输出从小到大排序后的10个整数
}
printf("\n");
return 0;
}
这里如果运行会得到错误的结果:
原因分析:
我们自己用选择排序法排序会发现在119之后(包括119)的顺序是不对的,仔细观察发现119是这10个数最大的数。
我们重新看代码,主要看执行算法的两个for循环主题部分:
for(i=0;i<=9;i++)
{
min=i;//记录初始需要换位置的数列元素下标
for(j=i+1;j<=9;j++)
{
if(a[i]>a[j])//按照从小到大的顺序排列(出问题的地方!)
{
i=j;//更新比较数据元素,同时记录最后一个待换数据元素的下标
}
}
temp=a[min];
a[min]=a[i];
a[i]=temp;//将第i+1个数据交换为此i+1轮遍历后的最小数
}
printf("The sorted numbers:\n");
原来是在if语句条件判断处出了问题:用的是a[ i ]来和a[ j ]比较。
那我们假设一个例子,如果第一个数a[ 0 ]就为最大数,在整个j循环下来,i的值最后变为了9,那么在交换这一轮后,i循环里i递增成为了10,即跳出循环,总共就只会交换这一轮,中间的数没有被排序。
解决办法:
将a[ i ]改为a[ min ], "i=j" 改为 "min=j" 避免更改i的数值从而影响外头的i循环执行。
代码:
#include <stdio.h>//选择排序法排序
int main()
{
int a[10],i,j,temp,min;
for(i=0;i<=9;i++)
{
printf("a[%d]:",i);
scanf("%d",&a[i]);//输入10个待排序的整数
}
printf("\n");
printf("The original numbers:\n");
for(i=0;i<=9;i++)
{
printf("%5d",a[i]);
}
printf("\n");
for(i=0;i<=9;i++)
{
min=i;//记录初始需要换位置的数列元素下标
for(j=i+1;j<=9;j++)
{
if(a[min]>a[j])//按照从小到大的顺序排列
{
min=j;//更新比较数据元素,同时记录最后一个待换数据元素的下标
}
}
temp=a[min];
a[min]=a[i];
a[i]=temp;//将第i+1个数据交换为此i+1轮遍历后的最小数
}
printf("The sorted numbers:\n");
for(i=0;i<=9;i++)
{
printf("%5d",a[i]);//输出从小到大排序后的10个整数
}
printf("\n");
return 0;
}
结果:
修改成功!
总结:注意内循环的运行是否会改变控制外循环的变量值从而导致外循环异常运行!
如果这篇文章能够帮助到你,请给博主点个免费的赞鼓励一下吧~