思想

定义一个变量放最大值,这个最小值是相对来说的,大家都知道递归的时候n是一直减一的,而这个最大值就是从a[0]到a[n-1]的最大值。得出这个最大值之后,将它放入数组最后面,每次的最大值都放最后面,也就成了排序了

  • 这是典型的伪递归题,想明白这个其他就简单多了

题目

函数接口定义:

void sort(int a[],int n);

其中 a 和 n 都是用户传入的参数。函数用递归法对 a 数组中n 个数据按升序序排序。

裁判测试程序样例:

#include <stdio.h>
 void  sort(int a[],int n);
int main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
sort(a,10);
for(i=0;i<10;i++)
printf("%3d",a[i]);
return 0;
}

输入样例:

2 5 4 1 6 9 8 3 7 0

输出样例:

0 1 2 3 4 5 6 7 8 9

方法一

(法二的注释多写了点,看不懂第一个,可以看看第二个)

#include <stdio.h>
void sort(int a[], int n);
int main()
{
    int a[10], i;
    for (i = 0; i < 10; i++)
        scanf("%d", &a[i]);
    sort(a, 10);
    for (i = 0; i < 10; i++)
        printf("%3d", a[i]);
    return 0;
}
void sort(int a[], int n)
{
    if(n==0) return ;
    int t;
    int max=a[n-1];//因为是从后向前放
    for(int i=0;i<n;i++)
    {
        if(max<a[i])
        {
            t=a[i];
            a[i]=max;
            max=t;
        }//现在max里放的是1到此时的n中最大的数
    }
    a[n-1]=max;//把这几个数中最大的放最后面
    sort(a,n-1);
    
}

n逆序的话,只要把最大值改成最小值就可以了。只需改动一条代码

方法二:从前往后放,改变一下思路啦

每次取当前区间内的最小,把他们从前向后放

#include <stdio.h>
void sort(int a[], int n);
int main()
{
    int a[10], i;
    for (i = 0; i < 10; i++)
        scanf("%d", &a[i]);
    sort(a, 10);
    for (i = 0; i < 10; i++)
        printf("%3d", a[i]);
    return 0;
}

int i = 0;//定义一个外部变量
//每次取当前区间内的最小,把他们从前向后放
void sort(int a[], int n)
{
    if (i == n)//相当于当前区间是一个数的时候就不应再递推了,最后一个数也一定是最大的
        return;
    int min;//用来求当前区间的最小值
    min = a[i];//每次都把当前区间的第一个数作为第一个最小值用来比较
    int t;//用来交换

    for (int j = i + 1; j <= n - 1; j++)//这个循环是用来确定当前区间的最小值的
    {                       //有同学说,这样不会把一个数给覆盖了吗
        if (min > a[j])     //其实是不会的,他的值其实只是在变换位置
        {                   //第一次就把当前区间的第一个数拿出来,就相当于第一个位置就制空了,他的值在min里面
            t = a[j];       //最后这个循环结束载重新将真正的最小值给第一个位置
            a[j] = min;
            min = t;
        }
    }
    // for (int p = 0; p < 10; p++)
    //     printf("%3d", a[p]);
    // printf("\n"); //测试数据
    a[i] = min;             //将真正的最小值给第一个位置
    // printf("i=%d  min=%d\n", i, min);//测试用
    i++;    //目的是让这个数组区间一次一次减小,比如第一次是0-9,第二次是1-9,其实这个时候0位置已经是0-9里最小的了,以此类推
    sort(a, n);
}

不应该注册点个赞吗(! - !)

手痒写的第三个,发现这个更简单

核心用的是冒泡排序法。如果不了解冒泡的话,可以把它想成:有一个海浪,从第一个数一直跑到最后一个数,浪峰上的数是浪跑过去中的数里最大的,想象只要海浪经过的比浪峰上的数还大数,就把浪峰上的数扔下来,把那个大的再提留上去,这样一直到岸边,把最大的数放下。

#include <stdio.h>
void sort(int a[], int n);
int main()
{
    int a[10], i;
    for (i = 0; i < 10; i++)
        scanf("%d", &a[i]);
    sort(a, 10);
    for (i = 0; i < 10; i++)
        printf("%3d", a[i]);
    return 0;
}
void sort(int a[], int n)
{
    if (n == 0)
        return;
    int t;
    for (int i = 0; i < n; i++)
    {
        if (a[i] > a[i + 1])  //冒泡法前一个数和后一个数进行比较,如果大于就换,把大数放后面
        {
            t = a[i];
            a[i] = a[i + 1];
            a[i + 1] = t;
        }
    }
    // for (int i = 0; i < 10; i++)
    //     printf("%3d", a[i]);
    //     printf("\n");
    sort(a,n-1);
}