| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 575 人关注过本帖
标题:大神帮忙看一下,这一语句去掉的话为什么就不对了
只看楼主 加入收藏
代码艺术
Rank: 1
来 自:山东省青州市何官镇
等 级:新手上路
帖 子:24
专家分:4
注 册:2015-4-8
结帖率:100%
收藏
 问题点数:0 回复次数:8 
大神帮忙看一下,这一语句去掉的话为什么就不对了
程序代码:
#include<stdio.h>
#define N 10
int main(void)
{
    int i,j,k,t,a[N],min;
    for(i=0;i<N;i++)
        scanf("%d",&a[i]);
    for(i=0;i<N-1;i++)
    {
        k=i;//这一句话
        min=a[i];
        for(j=i+1;j<N;j++)
        {
            if(a[j]<min)
            {
                min=a[j];
                k=j;
            }
        }
        if(k!=i)
            {
                t=a[i];a[i]=a[k];a[k]=t;
            }
    }
    for(i=0;i<N;i++)
    printf("%d ",a[i]);
    printf("\n");
    return 0;
}


加上就没问题,去掉就得不到理想的结果,但是感觉没用啊,求大神解释一下,,本人新手,,
2015-05-06 11:20
陆思雨
Rank: 2
等 级:论坛游民
威 望:1
帖 子:36
专家分:42
注 册:2014-9-17
收藏
得分:0 
去掉也是对的啊
2015-05-06 12:24
陆思雨
Rank: 2
等 级:论坛游民
威 望:1
帖 子:36
专家分:42
注 册:2014-9-17
收藏
得分:0 
因为后面你要判断    if(k!=i)  如果去掉那句,k!=i  这个语句就一定为真了
2015-05-06 12:27
林月儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:138
帖 子:2277
专家分:10647
注 册:2015-3-19
收藏
得分:0 
回复 3楼 陆思雨
当第一个数就是最小值去掉这句应该是不对的,以为这样的话k一直未被赋值导致相应的问题程序应该会报错。当然如果这种情况不存在那就如你所说可以删掉。个人看法,仅供参考。

剑栈风樯各苦辛,别时冰雪到时春
2015-05-06 12:48
取名字
Rank: 8Rank: 8
等 级:贵宾
威 望:21
帖 子:236
专家分:924
注 册:2015-4-27
收藏
得分:0 
    楼主的程序是一个选择排序法。其中k的作用是存储每一轮比较中找到的最小的元素的下标:首先将k设置为每一轮比较中第一个元素的下标(k=i),然后进行一轮比较,在比较中如果有比这一轮第一个元素更小的元素,则将其下标值存入k中(k=j),一轮比较结束后,将k的值与本轮比较中第一个元素的下标比较(if(k!=i)),如果相等,说明这轮比较中没有比第一个元素(本轮比较中的第一个元素)更小的元素了,则不用互相交换;如果不相等,说明这轮比较中找到了比第一个元素(本轮比较中的第一个元素)更小的元素,则将这个更小的元素与第一个元素(本轮比较中的第一个元素)互换(t=a[i];a[i]=a[k];a[k]=t;)。这样,全部比较完后,数组中的元素就按从小到大的顺序排列好了。
    如果将“k=i”这一句去掉,则在第一轮比较中,如果(if(a[j]<min))一直不成立的话,则“k=j”这一句就不能得到执行,k也就不能得到有效的初始化,其中存放的值就是毫无意义的垃圾值,在“if(k!=i)”的条件表达式中其比较结果就是不可预测的,这是一,另外,如果k在某一轮比较中被赋值了,导致“if(k!=i)”值为真,执行后面的元素交换语句,而在下一轮中因为“if(a[j]<min)”一直不成立,“k=j”这一句又没有得到执行,则k还是上一轮比较中被赋的值,当执行到“if(k!=i)”时,与上一轮结果一样,又执行后面的元素交换,这时就得到了错误的结果。所以“k=i”这一句不能去掉,它使k在每一轮比较结束后都被赋值为新一轮比较的第一个元素,从而重新去比较,这样就保证不会得到错误的结果。
    楼主的程序还可以优化为下面的形式:
#include <stdio.h>
#define N 10
int main(void)
{
    int i,j,k,t,a[N];
    for(i=0;i<N;i++)
        scanf("%d",&a[i]);
    for(i=0;i<N-1;i++)
    {
        k=i;//这一句话
        for(j=i+1;j<N;j++)
        {
            if(a[j]<a[k])
            {
              k=j;
            }
        }
        if(k!=i)
            {
                t=a[i];a[i]=a[k];a[k]=t;
            }
    }
    for(i=0;i<N;i++)
    printf("%d ",a[i]);
    printf("\n");
    return 0;
}


2015-05-06 13:51
calix
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:28
帖 子:249
专家分:1442
注 册:2015-5-4
收藏
得分:0 
k=i; k记录当前要比较的那个数的位置
如果内层循环中出现比min还小的数,k就不等于i了
后面的if(k!=i)就是判断内层循环执行结果的

所以k=i;一定要有
2015-05-06 13:52
代码艺术
Rank: 1
来 自:山东省青州市何官镇
等 级:新手上路
帖 子:24
专家分:4
注 册:2015-4-8
收藏
得分:0 
回复 5楼 取名字
终于明白了!!!谢谢大神!!
2015-05-06 18:38
代码艺术
Rank: 1
来 自:山东省青州市何官镇
等 级:新手上路
帖 子:24
专家分:4
注 册:2015-4-8
收藏
得分:0 
回复 6楼 calix
嗯,谢谢大神,搞懂了!
2015-05-06 18:38
我叫K
Rank: 2
等 级:论坛游民
帖 子:74
专家分:19
注 册:2015-4-28
收藏
得分:0 
话说我以前刚学这个的时候也有这个疑惑,我觉得这个东西何必要用,还有当时自己写的代码,又不是选择又不是冒泡,不过这种是效率低了,
---->>>
程序代码:
#include"stdio.h"
main()
{
    int a[50];
    int i,j,t,n;

 
     scanf("%d",&n);
     
     for(i=0;i<n;i++)
         scanf("%d",&a[i]);
     
     for(i=0;i<n;i++)
        printf("%d  ",a[i]);
     printf("\n");
     
     for(i=0;i<n;i++)
     {
         
         for(j=i;j<n;j++)
         {
             if(a[j]<a[i])
             {
                 t=a[i];
                 a[i]=a[j];
                 a[j]=t;
             }
             
         }
    
    }
    
    for(i=0;i<n;i++)
    printf("%d  ",a[i]);
    
}



其实有些东西记住个用法形式也是很重要的,就是要用到时候就当做个工具就出来了,当然没有深的理解也是难得.

他们和我说,喜欢一个女生要大胆追!
2015-05-06 20:49
快速回复:大神帮忙看一下,这一语句去掉的话为什么就不对了
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027636 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved