c语言直接插入排序数组报错什么情况?

#include<stdio.h>

void paiXu(int arr[], int len) {
    int i = 1;
    int tmp;
    int j = i - 1;
for (i = 1; i <= len; i++)
    {
        tmp = arr[i];
        for (int j = i - 1; j >= 0; j--)
        {
            if (tmp < arr[j])
            {
                arr[j + 1] = arr[j];
            }
        }
        arr[j + 1] = tmp;
    }
    printf("%d", arr[i]);
}
int main() {

    //定义一个数组
    int arr[9] = { 9,5,6,3,2,1,4,7,8 };
    int len = sizeof(arr) / sizeof(arr[0]);
    paiXu(arr, len);
    return 0;
}


```    直接插入排序
![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/847326466586117.jpg "#left")

这段代码存在几个问题导致出错:

  1. 在函数paiXu中,你在for循环之前声明了int j = i - 1;,然后在for循环内部又重新声明了一个同名的局部变量int j,这会导致变量覆盖和错误的结果。你应该在函数开头只声明一次int j = i - 1;,并删除for循环内部的变量声明。

  2. 在内层的for循环中,你漏掉了一个关键的步骤,即将tmp插入到正确的位置上。你需要在找到合适位置后,将tmp赋值给arr[j + 1]。可以在if语句块后添加一行arr[j + 1] = tmp;来完成这一步骤。

  3. 在打印结果时,你在循环外部使用了变量i,但实际上循环结束后,i的值已经超过了数组的长度。你可以将打印结果的代码移动到循环内部,并将其放在循环结束后进行输出。

下面是修改后的代码:

#include <stdio.h>

void paiXu(int arr[], int len) {
    int i, j, tmp;
    
    for (i = 1; i < len; i++) {
        tmp = arr[i];
        j = i - 1;
        
        while (j >= 0 && tmp < arr[j]) {
            arr[j + 1] = arr[j];
            j--;
        }
        
        arr[j + 1] = tmp;
    }
    
    for (i = 0; i < len; i++) {
        printf("%d ", arr[i]);
    }
}

int main() {
    int arr[9] = { 9, 5, 6, 3, 2, 1, 4, 7, 8 };
    int len = sizeof(arr) / sizeof(arr[0]);
    
    paiXu(arr, len);
    
    return 0;
}

修改后的代码使用了正确的插入排序算法,并将结果正确地打印出来。

我这里不报错
但你的printf写的不对
首先它在循环外面
其次你应该单独一个循环打印数组,不要混在排序的过程中

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7686993
  • 你也可以参考下这篇文章:c语言 如何用指针来处理字符串?
  • 同时,你还可以查看手册:c语言-常量及字面量 中的内容
  • 除此之外, 这篇博客: c语言从入门到精通中的 什么是进制? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 答:逢n进1
    

    计算机是由无数个0和无数个1组成
    我们先由二进制转换

    二进制转八进制方法: 取三合一法,即从二进制的小数点为分界点,向左(或向右)每三位取成一位
    二进制:1010 0100B
    八进制:010 100 100
    		2	4	 4
    最后的结果为244
    
    二进制转十进制方法
    135D = 128D + 7D = 1000 0111B
    去比对最大的数与那个数最接近,该位置1,用余数继续对比,直到为0
    
    11111111二进制
    1286432168421十进制
    二进制转十六进制:取四合一法,即从二进制的小数点为分界点,向左(或向右)每四位取成一位。
    二进制:		1010 0100B
    十六进制:	1010 0100
    			  a    4
    最后结果为a4
    
  • 您还可以看一下 王健伟老师的C语言入门篇课程中的 数组作为函数参数小节, 巩固相关知识点

修改如下,供参考:

#include<stdio.h>
void paiXu(int arr[], int len) {
    int i, j;      // 修改
    int tmp;
    //int j = i - 1; //修改
    for (i = 1; i < len; i++) //for (i = 1; i <= len; i++) 修改
    {
        tmp = arr[i];
        for (j = i; j > 0 && arr[j - 1] > tmp; j--) //for (int j = i - 1; j >= 0; j--) 修改
        {
            //if (tmp < arr[j])修改
            //{                修改
            arr[j] = arr[j - 1];  // arr[j + 1] = arr[j]; 修改
            //}  修改
        }
        arr[j] = tmp;   //arr[j + 1] = tmp; 修改
    }
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);
}
int main() {

    //定义一个数组
    int arr[9] = { 9,5,6,3,2,1,4,7,8 };
    int len = sizeof(arr) / sizeof(arr[0]);
    paiXu(arr, len);
    return 0;
}