输入10个整数,按降序排列。冒泡法排序

1).用循环输入10个整数,放入数组中

首先,是的,数组名在很多上下文中被当作指向其第一个元素的指针。例如,如果你有一个数组`int numbers[10];`,那么表达式`numbers`在没有索引的情况下会被转换为指向数组首元素的指针。这意味着`numbers`等价于`&numbers[0]`,即指向数组第一个元素的指针。

然而,当我们在`scanf`中使用数组时,情况略有不同。`scanf`函数需要指针作为参数,以便知道在内存的哪个位置存储输入的值。当你使用`scanf`为数组的一个特定元素赋值时,你需要提供那个特定元素的地址。这就是为什么我们写`scanf("%d", &numbers[i]);`而不是`scanf("%d", numbers[i]);`:

- `&numbers[i]`提供了数组第`i`个元素的准确地址,告诉`scanf`将输入的整数存储在哪里。

- 如果你只写`numbers[i]`,那意味着你在尝试传递一个整数值(即数组第`i`个元素的当前值)给`scanf`,而不是一个地址。这会导致编译错误,因为`scanf`期望的是一个指向整数的指针,而不是一个整数值。

因此,即使数组名代表的是地址,当你需要引用数组中特定元素的地址时,你仍然需要使用`&`操作符。这样,你就能够提供一个明确的位置给`scanf`,以便它知道在哪里存储输入的数据。

(2).冒泡法进行排序

冒泡排序算法是一种简单的排序算法,它重复地遍历待排序的数列,一次比较两个元素,如果它们的顺序(如从小到大、从大到小)错误就把它们交换过来。遍历数列的工作会重复进行,直到没有再需要交换的元素为止,这时数列就完全排序好了。因为这种算法在排序过程中,较小(或较大)的元素会像"泡泡"一样逐渐"浮"到数列的顶端(开始或结束),所以被称为"冒泡排序"。

### 冒泡排序的基本步骤

1.比较相邻的元素。如果第一个比第二个大(要求从小到大排序的话),就交换它们两个。

2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

3. 针对所有的元素重复以上的步骤,除了最后一个。

4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

### 例子

假设我们有一个数列 `[5, 3, 8, 4, 2]`,我们想进行升序排序:

1. 第一轮遍历:

   - 比较5和3,因为5>3,交换位置:`[3, 5, 8, 4, 2]`

   - 比较5和8,因为5<8,不交换:`[3, 5, 8, 4, 2]`

   - 比较8和4,因为8>4,交换位置:`[3, 5, 4, 8, 2]`

   - 比较8和2,因为8>2,交换位置:`[3, 5, 4, 2, 8]`

   - 第一轮结束,最大的数8已经到了最右边。

2. 第二轮遍历:

   - 比较3和5,因为3<5,不交换:`[3, 5, 4, 2, 8]`

   - 比较5和4,因为5>4,交换位置:`[3, 4, 5, 2, 8]`

   - 比较5和2,因为5>2,交换位置:`[3, 4, 2, 5, 8]`

   - 此轮不再比较最后两个数,因为8已经是最大的。

3. 第三轮遍历:

   - 比较3和4,因为3<4,不交换:`[3, 4, 2, 5, 8]`

   - 比较4和2,因为4>2,交换位置:`[3, 2, 4, 5, 8]`

   - 再次,我们不需要比较到最后,因为最大的数已经在正确位置。

4. 第四轮遍历:

   - 只需比较第一对,因为3>2,交换:`[2, 3, 4, 5, 8]`

这时,数列已经完全排序。冒泡排序的效率并不高,特别是对于大数据集,因为它的平均时间复杂度和最坏时间复杂度都是O(n^2),其中n是数列的长度。但由于其算法的简单性,它在一些教育场景和简单应用中仍然非常有用。

这段代码是冒泡排序算法的具体实现,旨在对一个整数数组`numbers`进行降序排序。让我们逐步分解这个过程:

### 外层循环

- `for(i = 0; i < 9; i++) { ... }`

这个循环确保了整个排序过程能够重复执行足够的次数。对于一个包含10个元素的数组,我们需要进行9轮比较和可能的交换操作才能确保数组被完全排序。外层循环变量`i`从0开始,直到8结束,共进行9次迭代。

### 内层循环

- `for(j = 0; j < 9 - i; j++) { ... }`

内层循环负责在每一轮中执行实际的元素比较和交换操作。随着外层循环的每一次迭代,需要进行比较的元素数量会减少,因为最大的元素已经被冒泡到了数组的末尾。这就是`j < 9 - i`这个条件的作用,它逐渐减少内层循环的迭代次数

### 比较和交换

- `if(numbers[j] < numbers[j + 1]) { ... }`

这是冒泡排序的核心。在每次内层循环的迭代中,当前元素`numbers[j]`和它的下一个元素`numbers[j + 1]`被比较。由于我们的目标是降序排序,如果当前元素小于它的下一个元素,这意味着它们的顺序是错误的,所以需要交换这两个元素。这通过一个临时变量`temp`实现,以确保交换过程中不会丢失任何元素的值

### 整个过程

通过上述逻辑,每次外层循环完成后,最大的未排序元素被“冒泡”到它应该在的位置(即,它被交换到了当前未排序元素的最末端)。随着每次外层循环的迭代,排序所需比较的元素数量逐渐减少,直到排序完成。

这个过程高效地确保了每轮比较后,未排序部分的最大值会被推移到正确的位置,最终达到整个数组的降序排序。

(3)输出

为什么`printf`不需要`&`??

当你调用`printf("%d ", numbers[i]);`时:

- `"%d"`告诉`printf`你想要输出一个整数。

- `numbers[i]`给出了这个整数的值。在这个上下文中,`printf`需要的是值而不是地址,因为它的任务是展示这个值而不是去修改它。

        简而言之,使用`&`是为了获取变量的地址,这在你想要某个函数(如`scanf`)修改变量的值时是必需的。当你仅需要访问变量的值,如在使用`printf`时,直接使用变量名或数组加索引即可。

(4).完整代码

#include<stdio.h>
int main()
{
    int numbers[10] = { 0 };
    int i = 0;
    int j = 0;
    int temp = 0;
    for (i = 0; i < 10; i++)
        scanf("%d", &numbers[i]);
    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 9-i; j++)
        {
            if (numbers[j] < numbers[j + 1])
            {
                temp = numbers[j];
                numbers[j ] = numbers[j+1];
                numbers[j+1] = temp;
            }
        }
    }
    for (i = 0; i < 10; i++)
        printf("%d ", numbers[i]);
    return 0;
}

  • 49
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值