湖师大C语言实验期末复查(完结)

实验(十七)冒泡排序

知识点复查

实验内容

实验代码实现

#include<stdio.h>
void bubble(int m[],int size) {
	for (int i = 0;i < size-1;i++) {//这一步的思路是每次都将最大的数放到最后面
		for (int j = 0;j < size - i - 1;j++) {//每次都将最大的数放到最后面,所以每次比较的范围都要减小
			//为什么用嵌套循环
			 if (m[j] > m[j + 1]) {
				 int temp = m[j];
				 m[j] = m[j + 1];
				 m[j + 1] = temp;
			 }
		 }
	 
	 }
}
int main() {
	int n=0;
	scanf("%d", &n);
	int m[11];
	if (n <= 0 || n >= 10) {
		printf("ERROR");
	}
	else {
		for (int i = 0; i < n; i++) {
			scanf("%d", &m[i]);
		}
	}
	bubble(m,n);
	for (int i = 0; i < n; i++) {
		printf("\t%d", m[i]);
	}
	return 0;
}

编写总结

首先不管这个代码怎么运行,需要搞清楚输入和输出,输入n作为参与排序的数字个数,然后依次输入n个数字填入一个数组中(这个过程也即对数组初始化),然后用某个函数对数组进行(从小到大)排序得到排序后的数组,然后通过循环遍历数组作为输出。

那么我们就要定义一个函数用于对数组元素进行排序,那么怎么进行排序就是函数最核心的地方。

冒泡排序的逻辑:相邻元素作比较(如果大家看我的解释看不懂的话,就搜一下冒泡排序的动画演示)。

我想重点讲一下为什么要嵌套循环,内部循环执行是为了对相邻元素比较并移位,每次都会执行m[0]与m[1]的比较,m[1]与m[2]的比较,m[2]与m[3]的比较,,,那就有个问题,这些步骤肯定能保证最大的元素来到了数组末尾,那其他元素呢,假设数组为【5,7,4,3,2】那么执行一次,会变成【5,4,3,2,7】,因此我们还需要多次(至少要执行4次,因为有5个元素)这样的循环比较,我们下次需执行m[0]与m[1]的比较,m[1]与m[2]的比较,m[2]与m[3]的比较,我们不需要再考虑m[3]与m[4]的比较,因为上次循环比较,我们已经确保了倒数第一是最大数,所以每执行一次循环比较,下次循环就少一次比较,执行一次少一次比较。回看实验代码,对照着理解即可。

1. 算法原理

  • 基本思想:通过对待排序序列从前向后(从下表较小的元素开始),依次比较相邻元素的排序码,若发现逆序则交换,使排序码较大的元素逐渐从前部移向后部(像冒泡一样)。因为排序的过程中,各元素不断接近自己的位置,如果一轮比较后没有任何元素交换,则排序完成,否则需要继续进行比较和交换。

  • 比较次数:对于长度为 n 的序列,第一轮比较需要比较 n−1 次,第二轮比较需要比较 n−2 次,以此类推,总共需要比较的次数为 2n(n−1)​ 次。

2. 算法步骤

  1. 比较相邻的元素:如果第一个比第二个大(升序排列),就交换它们两个。

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

  3. 针对所有的元素重复以上的步骤:除了最后一个,因为在每次遍历中,最大的数已经被排到了最后。

  4. 重复步骤1~3:直到没有任何一对数字需要比较。

实验(十八)报数

知识点复查

实验内容

实验代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int n, m;
    scanf("%d%d", &n, &m);

    // 检查输入是否符合要求
    if (n <= 0 || n >= 20 || m <= 0 || m >= 20) {
        printf("ERROR\n");
        return 0;
    }

    int people[20]; // 假设人数不会超过20
    for (int i = 0; i < n; i++) {
        people[i] = i + 1; // 初始化编号
    }

    int index = 0; // 从第一个人开始
    int count = 0; // 计数器,用于报数
    int total = n; // 总人数
    int out_count = 0; // 已出列人数

    while (out_count < n) {
        if (people[index] != 0) { // 如果这个人还在圈中
            count++;
            if (count == m) { // 如果报数到m,出列
                printf("\t%d", people[index]);
                count = 0; // 重置计数器
                people[index] = 0; // 标记为已出列
                out_count++;
            }
        }
        index = (index + 1) % n; // 移动到下一个人
    }
    printf("\n"); // 添加换行符
    return 0;
}

编写总结

代码编写的难点在于,第一叫到人出列,下一个报的m的人的位置怎么确定。

  1. 初始化一个数组来表示围成一圈的人,每个人有一个编号。

  2. 使用一个变量index来表示当前位置,初始值为0。

  3. 使用一个变量out-count来记录已经出列的人数。

  4. 使用一个循环,直到所有人都出列:

    • 计算出列位置:index = (index + m - 1) % total;

    • 输出出列人的编号。

    • 将出列的人从数组中移除,并更新index(从下一个人开始报数)total

  5. 如果输入不符合要求,输出“ERROR”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值