冒泡排序为什么输出后左边有个很大的负值


#include<stdio.h>
void main(){    
    int shu[]={3,9,-1,10,-2,-11,989,123,436,900,-1234};
    int t;
    int i;
    int j;
int k = sizeof(shu)/sizeof(int);
    for(j=0;j<k;j++){
    for(i=0;i<k-j;i++){
        if(shu[i]>shu[i+1]){
        t=shu[i];
        shu[i]=shu[i+1];
        shu[i+1]=t;}
    }}
        for(j=0;j<k;j++){
        printf("  %d",shu[j]);
        }
getchar();}

题主的代码,问题在第9 10 两行里,for()循环的边界值越界了,修改如下,改动处见注释,供对照参考:

#include<stdio.h>
int  main() {    //void main()  修改
    int shu[] = { 3,9,-1,10,-2,-11,989,123,436,900,-1234 };
    int t;
    int i;
    int j;
    int k = sizeof(shu) / sizeof(int);
    for (j = 0; j < k - 1; j++) {         //for (j = 0; j < k; j++) 修改      
        for (i = 0; i < k - j - 1; i++) { //for (i = 0; i < k - j; i++) 修改
            if (shu[i] > shu[i + 1]) {
                t = shu[i];
                shu[i] = shu[i + 1];
                shu[i + 1] = t;
            }
        }
    }
    for (j = 0; j < k; j++) {
        printf("  %d", shu[j]);
    }
    //getchar();  修改
    return 0;
}

冒泡这样写:

#include<bits/stdc++.h>
using namespace std; 
int main()
{
    int a[100];
    int n;
    cin>>n;//输入排序长度
    for(int i=1;i<=n;i++) cin>>a[i];//输入排序数组 
    for(int i=1;i<=n-1;i++){
        for(int j=i+1;j<=n;j++)
        {
            if(a[j]<a[i]) swap(a[i],a[j]);
        }    
    } 
    for(int i=1;i<=n;i++) cout<<a[i]<<" "; 
    return 0;
}

应该是因为第10行里的for循环结束条件为i<k-j , 然后 i 最大可以为 k-1,,则 i+1 最大可为 k,超出了数组的最大下标 k-1,然后越界访问别的内存时,恰好这个位置有个很大的负值,经过冒泡排序后就会赋值到数组最左边, 所以结果就出错了;

可以将第10行for循环的结束条件改为:i<k-j-1 即可, 然后第9行for循环的比较趟数也可以改为k-1。

修改如下:

参考链接:


#include<stdio.h>

int  main() {
    int shu[]= {3,9,-1,10,-2,-11,989,123,436,900,-1234};
    int t;
    int i;
    int j;
    int k = sizeof(shu)/sizeof(int);
    // https://baike.baidu.com/item/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F/4602306
    for(j=0; j<k-1; j++) {
        for(i=0; i<k-j-1; i++) {
        //    printf("shu[%d]=%d,shu[%d]=%d\n",i,shu[i],i+1,shu[i+1]);
            if(shu[i]>shu[i+1]) {
                
                t=shu[i];
                shu[i]=shu[i+1];
                shu[i+1]=t;
            }
        }
    }
    for(j=0; j<k; j++) {
        printf("  %d",shu[j]);
    }
    getchar();
}


img

你是从小打到大排序呀,还有你确定你这代码能运行起来?
代码我帮你改了下,1.从小到大,2.从大到小两种
1.从小到大

#include<stdio.h>
int main(void) {    
    int shu[]={3,9,-1,10,-2,-11,989,123,436,900,-1234};
    int t;
    int i;
    int j;
    int k = sizeof(shu)/sizeof(int);
    for(j=0;j<k-1;j++){ 
        for(i=0;i<k-1-j;i++){ 
            if(shu[i]>shu[i+1]){
                t=shu[i];
                shu[i]=shu[i+1];
                shu[i+1]=t;
            }
        }
    }
    for(j=0;j<k;j++){
        printf("  %d",shu[j]);
    }
    getchar();
    return 0;

}   

2.从大到小

#include<stdio.h>
int main(void) {    
    int shu[]={3,9,-1,10,-2,-11,989,123,436,900,-1234};
    int t;
    int i;
    int j;
    int k = sizeof(shu)/sizeof(int);
    for(j=0;j<k-1;j++){ 
        for(i=0;i<k-1-j;i++){ 
            if(shu[i]<shu[i+1]){
                t=shu[i];
                shu[i]=shu[i+1];
                shu[i+1]=t;
            }
        }
    }
    for(j=0;j<k;j++){
        printf("  %d",shu[j]);
    }
    getchar();
    return 0;

}    


不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7547419
  • 你也可以参考下这篇文章:在字符串中找出最大的字符并移到首位
  • 除此之外, 这篇博客: 如何输入多组数据并输出每组数据的和?中的 如何输入多组数据? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    下面我分三种语言讲解这个问题

    1. C语言
    先讲解一下scanf的返回值,假设说scanf读入一个数字或者字符并成功。例如:scanf("%d, &x),那么返回值为1。类似的,两个字符成功后返回值为2,以此类推。假如读入不成功,则返回值为EOF。

    开始我曾想利用字符串或者其他形式一行一行读入,全读完之后再输出,后来发现无法办到。于是我改变思路,试图读一个数操作一次。那么怎么知道一行读完了并且输出每行的和数呢?先卖个关子。

    显而易见,如何读入多组数据输出每组的和,代码如下

    #include<stdio.h>
    int main(void)
    {
    	int x, total = 0;
    	while(scanf("%d", &x) != EOF{
    		sum += x;
    		if(getchar() == '\n')
    		{
    			printf("%d\n", total);
    			total = 0;
    		}
    	}
    	return 0;
    }
    

    2. C++
    再讲一些预备知识,cin不是一个操作符,而是一个对象,这也是我最近才知道的。所以while(cin << x)的返回值是cin的值,即也是x的值。这个操作既实现了给x赋值,又实现了判断是否到了输入末尾,相较于C语言省略了EOF,简洁。
    代码没有大的变动,故不附。

    3. Python
    我在用python写时也遇到了一个问题,这一个地方来来回回改了五回。python语言一般在input()后需要立即输入一个数,所以在实现同时输入两个数的时候需要有一个小技巧。需要将两个数作为一个字符串读入并用函数分割再转化为整型,代码如下:

    while True:  
    	try:  
        	x,y=map(int,input().split())  
            print(x + y)  
    	except:  
            break  
    
    

    其中,map第二个参数是被执行的元素,第一个参数是执行的函数,在这个代码中就是讲x和y同时整型化。

  • 您还可以看一下 孙玖祥老师的图解数据结构与算法课程中的 循环队列的入队出队扩容操作小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    问题原因: 在冒泡排序过程中,可能会出现一个很大的负值在输出的左边,这是由于排序算法中的错误导致的。

    解决方案: 这个问题一般是由于排序算法中的错误导致的,我们可以通过以下几个步骤来解决这个问题:

    1. 检查排序算法实现的代码:
    2. 首先,检查冒泡排序算法的实现代码,确保没有错误或遗漏了关键步骤。冒泡排序的基本思想是,比较相邻的两个元素,如果顺序不对则交换位置,直到整个序列都有序为止。
    3. 确保代码中没有错误的边界条件,例如数组越界或错误的索引值。
    4. 确保在比较和交换过程中,元素的类型被正确地处理,例如确保比较的是数值类型而不是字符串类型。

    5. 检查输入数据:

    6. 检查输入数据是否包含任何非数值类型的元素,如果有,可能会导致比较和交换过程中的错误。
    7. 检查输入数据是否包含较大或较小的数值,这可能会导致计算机无法处理或产生溢出的结果。

    8. 使用断点调试工具:

    9. 如果无法通过代码检查找到错误,可以使用调试工具来跟踪代码执行过程。可以使用Python的pdb模块或其他调试器来设置断点,并逐步跟踪代码执行过程,观察变量的值和代码执行的顺序,以便找到错误所在。

    如果经过以上步骤,问题仍然存在,那么可能是代码实现中存在逻辑错误或其他特定问题,需要进一步分析和调试。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^