在学完C语言基础后,C语言程序设计“数组”部分的选择排序与冒泡排序的学习是很多学生学习C语言的分水岭,如何学好C语言的排序,对整个C语言的学习,乃至大学其他课程的学习来说都至关重要,是对学生能力的检验与锻炼。那么,本文从以下两方面帮助学生提高学习的性能和学习能力:(1) 大模型辅助学习,理解了吗?(2) 技术本质探究,真的理解。
(1) DeepSeek辅助学习
有了大模型,如Kimi, 文心一言, 通义千问, 当然还有DeepSeek,很多同学在利用大模型辅助学习的时候一般存在以下两种层次:
1) 完全依赖的一知半解
针对“C语言的选择和冒泡排序问题”,很多同学是这样问的:“如何学习C语言的选择和冒泡排序,给些例子”,下面是DeepSeek给出的冒泡排序部分:
* 冒泡排序通过重复地遍历列表,比较相邻元素并交换它们的位置,直到列表有序。
* 时间复杂度:O(n^2)
示例代码:
#include
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n-1; i++) {
// 每次遍历将最大的元素“冒泡”到最后
for (j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
// 交换相邻元素
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
学习建议:
* 理解算法原理:先通过伪代码或图示理解算法的基本思想。
* 编写代码:根据理解编写C语言代码,并逐步调试。
* 调试与优化:通过调试工具检查代码的正确性,并尝试优化代码。
* 实践练习:多做一些排序相关的练习题,如对不同的数组进行排序,观察算法的执行过程。
看到DeepSeek给出的内容,同学会发现,示例代码和教材差不多,学习建议还是要自己理解。
2) 辅助学习工具的豁然开朗
很多同学在得到第一个问题的答复后,就直接放弃了,对“C语言排序”的理解没有加强,学习能力没有得到提升。实际上,在第一个问题的基础上,第二层次的同学会冷静的思考问题的关键并引导大模型辅助学习。显然,排序的关键在于两重循环的深入理解,而示例代码中没有给出同学所需的“深入理解”,为此,可以继续发问,如“对以上选择排序和冒泡排序中的两重for循环还不是很理解,从循环变量的控制意义方面帮我解释一下”,DeepSeek会给出如下回答(冒泡排序部分):
代码回顾:
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n-1; i++) { // 外层循环
for (j = 0; j < n-i-1; j++) { // 内层循环
if (arr[j] > arr[j+1]) {
// 交换相邻元素
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
循环变量的控制意义:
1. 外层循环(i循环)
* 作用:控制冒泡的轮数;
* 范围:i从0到n-2(即i<n-1)
* 意义:每轮外层循环结束后,最大的元素会被“冒泡”到未排序部分的末尾。
举例:
* 当i=0时,第一轮冒泡,最大的元素被放到 arr[n-1]。
* 当i=1时, 第二轮冒泡,次大的元素被放到 arr[n-2]。
* 以此类推,直到整个数组有序。
2. 内层循环(j循环)
* 作用:在未排序部分中进行相邻元素的比较和交换。
* 范围:j从0到n-i-2(即j<n-i-1)
* 意义:遍历未排序部分,比较相邻元素并交换,确保最大的元素“冒泡”到未排序部分的末尾。
举例:
* 当i=0时,j从0到n-2,比较并交换相邻元素,最大的元素被放到arr[n-1];
* 当i=1时,j从0到n-3,比较并交换相邻元素,次大的元素被放到arr[n-2]。
显然,通过增加这一次问答,能够显著增强学生对“C语言排序”的理解。
(2) 技术本质探究,学习能力提升
对于极少部分学习能力强喜欢探究的学生来说,对以上回答可能还不够满意,隐隐的对“选择”和“冒泡”的本质还是有一层窗户纸没有捅破。为此,本文期望帮助所有人捅破这层“窗户纸”,深入理解选择排序和冒泡排序的本质。
“大道至简”,其实理解两种排序法的关键其实就是“选择”与“冒泡”两个词。具体的,需要弄清如下两个问题来更好的理解排序的两重循环:
1) 找到哪个数组元素的顺序排序位置;
2) 怎么找到排好序元素的位置。
那么,对于选择排序,以上两个问题就变为:
1) 选择出哪个(排序好的)数组元素;
2) 如何选择出这个元素。
对应的二重循环为:
for(i=0; i<n-1; i++) // i控制选择出排序好的数组元素的索引,
//i从0到n-2(i<n-1)正序(i++),选择出arr[n-2]后,arr[n-1]也就排好了。
{// 假设当前arr[i]已经排好序,即是当前未排序数据中的最小(升序)或
// 最大(降序)值
for(j=i+1; j<n; j++) // 通过与当前arr[i]逐个比较,选择出排序好的arr[i]
//arr[i]需要与后面所有元素比较,即j从i+1到n-1 (j<n)
{
if(arr[i] > arr[j]) //以升序为例,假设arr[i]最小不成立,需要交换
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
对于冒泡排序,以上两个问题就变为:
1) 冒泡出哪个(排序好的)数组元素;
2) 如何将目标数组元素冒泡出来。
对应的二重循环为:
for(i=n-1; i>0; i--) // i控制冒泡出排序好的数组元素的索引,根据冒泡顺序,
//i从n-1到1(i>0)倒序(i--),arr[1]冒泡出来后,arr[0]就排好了。
{// 假设当前arr[i]已经排好序,即是当前未排序数据中的最小(升序)或
// 最大(降序)值
for(j=0; j<i-1; j++) // 数组元素序号0到i-1相邻元素逐个比较完成冒泡
//即j从0到i-2 (j<i-1)
{
if(arr[j] > arr[j+1]) //以升序为例,arr[j]与arr[j+1]顺序不符,需要交换
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
显然,通过以上内容可以更加深刻的理解C语言的选择和冒泡排序方法。综上所述,可以看到,在AI技术突飞猛进的时代,我们学习的速度会成倍增加,学习能力的差距也随之显著增大,为了有效跟上时代,将AI技术为我所用,需要学生静下心来理解自己要学习什么,学习的难点和关键点是什么,要保持一颗探究的心在终生学习的道路上不断提升自己。