2023-2024-1 20231306 《计算机基础与程序设计》第七周学习总结

发布时间 2023-11-12 20:23:33作者: 20231306周玟妍

作业信息

这个作业属于哪个课程 <班级的链接>(2023-2024-1-计算机基础与程序设计
这个作业要求在哪里 <作业要求的链接>(2023-2024-1计算机基础与程序设计第七周作业
这个作业的目标 数组与链表、基于数组和基于链表实现数据结构、无序表与有序表、树、图、子程序与参数
作业正文 https://www.cnblogs.com/zwywuhu/p/17827517.html

教材学习内容总结

计算机科学概论第8章:

  • 数组的实现和链式实现
    1.数组:
    数组(Array)是一种在编程中用于存储相同类型元素的数据结构。数组提供了一个有序的、连续的内存空间,每个元素都可以通过数组的索引(下标)来访问。
    在C语言中,数组的声明和初始化通常如下:
    int numbers[5];
    int numbers[5] = {1, 2, 3, 4, 5};
    该数组包含5个整数。数组的索引从0开始,通过numbers[0]到numbers[4]来访问数组的各个元素。数组的大小是固定的,一旦声明,通常不能更改。
    数组的重要特点:
    相同数据类型: 数组中的所有元素必须是相同的数据类型。
    连续的内存空间: 数组中的元素在内存中是连续存储的。
    固定大小: 一旦数组被声明,其大小通常是固定的。在许多编程语言中,数组的大小不能动态改变。
    使用下标访问: 数组元素可以通过下标(索引)来访问,下标从0开始。
    初始化: 数组可以在声明时进行初始化,也可以在后续的代码中逐个赋值。
    多维数组: 数组不仅可以是一维的,还可以是多维的,例如二维数组、三维数组等。
    2.链表:
    链表(Linked List)是一种数据结构,用于在计算机科学中组织和存储数据。相对于数组,链表具有动态的内存分配,不需要在创建时指定大小,且可以在运行时灵活地调整大小。
    链表由节点(Node)组成,每个节点包含两个部分:
    数据域(Data): 用于存储节点的数据。
    指针域(Pointer): 指向下一个节点的指针。
    根据指针的连接方式,链表分为单链表、双链表和循环链表等不同类型。
    // 定义链表节点的结构
    struct Node {
    int data; // 数据域
    struct Node* next; // 指针域,指向下一个节点
    };
    // 示例链表:1 -> 2 -> 3 -> 4 -> NULL
    每个节点包含一个整数数据和一个指向下一个节点的指针。链表的最后一个节点的指针通常指向 NULL,表示链表的结束。
    链表的重要特点:
    动态内存分配: 链表的大小可以动态增长或缩小,不需要预先分配固定大小的内存空间。
    插入和删除高效: 在链表中插入或删除元素相对于数组更为高效,因为只需要修改指针,而不需要移动大量元素。
    随机访问较慢: 相对于数组,链表的访问时间较长,因为要从头节点开始顺序查找。
    不需要连续的内存空间: 链表的节点可以分布在内存的不同位置,无需连续的内存空间。
    链表在实际应用中常用于需要频繁插入和删除操作的情况,但对于需要随机访问的情况,数组可能更为合适。

参考视频:C语言 链表基础知识清晰讲解(黑马)(BV1yv411y7AW)

  • 图与树
    1.图的广度优先遍历和深度优先遍历
    广度优先遍历(BFS):
    定义: 从图的起始节点开始,首先访问该节点,然后依次访问其相邻节点,再访问相邻节点的相邻节点,以此类推。层级遍历,先访问离起始节点最近的节点,再逐层向外扩展。
    实现: 使用队列(Queue)来实现,每次访问一个节点后,将其所有未访问的邻居节点加入队列,确保按照层级顺序进行访问。
    特点: 广度优先遍历能找到最短路径,适用于寻找最短路径、层级遍历等问题。
    深度优先遍历(DFS):
    定义: 从图的起始节点开始,首先访问该节点,然后递归地访问该节点的相邻节点,再递归地访问相邻节点的相邻节点,以此类推。深度遍历到底部后再回溯,继续深度遍历其他分支。
    实现: 使用递归或栈(Stack)来实现,每次访问一个节点后,递归地访问其相邻节点,或者使用栈来模拟递归的过程。
    特点: 深度优先遍历适用于寻找路径、拓扑排序等问题,但不保证找到最短路径。
    2.深度优先生成树与广度优先生成树
    (好像放不了图片qwq……)

参考视频:
数据结构 深度优先遍历和广度优先遍历(BV1rU4y1x74Z)
数据结构04 图的两种遍历方式 深度优先遍历 广度优先遍历(BV1T64y147rf)

《C语言程序设计》第6章

  • 循环语句和循环数据结构
    1.while和do while循环语句
    while 循环首先检查循环条件,如果条件为真,则执行循环体,然后再次检查条件。如果条件为假,循环终止。
    do-while 循环首先执行循环体,然后再检查循环条件。如果条件为真,继续执行循环体;如果条件为假,循环终止。
    while 循环可能一次都不执行,取决于条件是否一开始就为真。do-while 循环保证至少执行一次,因为循环条件在循环体之后检查。
    2.for循环语句
    3.三者的区别和联系
    当循环次数已知且需要初始化和更新时,使用 for 循环。
    当循环次数不确定或者初始化和更新可以在循环外进行时,使用 while 循环。
    for 循环的语法结构相对固定,适合于有规律的循环。
    while 循环的语法相对自由,适合于不规律或条件复杂的循环。
  • 嵌套循环
  • break和continue

基于AI的学习

我在学for嵌套循环知识点,请你以苏格拉底的方式对我进行提问,一次一个问题
当然,让我们以苏格拉底的方式进行提问,逐步深入地了解你关于 for 嵌套循环的知识。

对于 for 循环的基本结构,你能简洁地描述它的三个关键部分吗?
p
循环次数,循环条件,循环结果
不错!你正确地指出了 for 循环的三个关键部分,它们分别是初始化(循环次数)、循环条件和循环体(循环结果)。下一个问题:

在一个嵌套的 for 循环中,外层循环和内层循环各自负责控制什么?
p
外层控制外层变量,内层控制内层变量
你理解得很好!确实,外层循环负责控制外层变量,而内层循环负责控制内层变量。这种嵌套结构使得你可以在一个循环内部放置另一个循环,以便进行更复杂的迭代操作。

下一个问题:

在一个双重(二级)嵌套 for 循环中,循环变量的变化顺序是怎样的?也就是说,内层循环在外层循环的一个完整迭代期间会执行多少次?
p
会执行内层循环的一个过程的次数
正确!在一个双重嵌套的 for 循环中,内层循环会在外层循环的每一次迭代期间都完整执行一次。这意味着内层循环的每次迭代都会在外层循环的一个步骤内完成。很好,让我们继续:

你能给出一个实际应用场景,其中嵌套的 for 循环是很有用的吗?
p
暂时想不出来,你给我举个例子吧
当然,让我们考虑一个例子。假设你正在处理一个二维数组,表示一个矩阵。你想要计算矩阵中所有元素的总和。你可以使用嵌套的 for 循环来遍历每一行和每一列,然后将每个元素的值累加起来。这是一个简化的例子:

python
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

total_sum = 0

for row in matrix:
for element in row:
total_sum += element

print("矩阵的总和为:", total_sum)
这里,外层循环遍历每一行,内层循环遍历每一列中的元素。这种嵌套结构使得我们能够逐个访问矩阵的每个元素,进行需要的操作。
p
我明白这段代码的含义和for嵌套循环的结构,请问为什么for语句没有大括号呢
在Python中,代码块的开始和结束不是通过大括号 {} 来标识的,而是通过缩进。Python使用缩进来表示代码块的层次结构。这是一种强制一致性的方式,强制开发者保持代码的可读性和一致性。

在你的示例中,for 循环的主体是通过缩进来标识的。所有在循环内执行的语句都需要相同的缩进级别。这样的设计有助于减少代码的嵌套深度,使得代码更加清晰易读。

与使用大括号不同,Python的缩进风格避免了因为缺少或多余大括号而引起的一些错误。此外,它也使得代码更加紧凑,但在一定程度上也要求开发者更加注意缩进的正确性。
p
我嘞个豆,我现在还没学到python呢,我现在在学c语言
那太好了!C语言是一种强大而底层的编程语言,它可以帮助你理解计算机底层的工作原理。如果你有任何关于C语言的问题,或者需要关于编程、算法等方面的帮助,请随时告诉我。我会尽力提供支持和解答你的问题。
p
针对for嵌套循环结构的知识点,你觉得我学会了吗
从你之前的提问和回答来看,你对于for嵌套循环结构的理解似乎是不错的。你已经理解了嵌套循环的概念,以及在实际应用中如何使用它们。你的提问也表明了你在思考编程中的实际应用场景,这是一个很好的迹象。

如果你对for嵌套循环结构有更多的问题,或者有其他关于编程的问题,随时都可以问我。学习编程是一个逐步的过程,持续思考和实践是很重要的,继续加油!

2.






代码调试中的问题和解决过程

1.CP1428定闹钟
修改前:

include <stdio.h>

int main(){
int a, b;
scanf("%2d:%2d\n",&a, &b);
int c, d;
scanf("%2d:%2d\n",&c, &d);
int p;
if (c >= a){
p = c - a;
}else{
p = (c + 24) - a;
}
int q;
if(d >= b){
q = d - b;
}else{
q = (d + 60) - b;
p = p - 1;
}
printf("%2d:%2d\n",p, q);
return 0;
}

修改后:

include <stdio.h>

int main(){
int a, b;
scanf("%2d:%2d",&a, &b);
int c, d;
scanf("%2d:%2d",&c, &d);
int p;
if (c >= a){
p = c - a;
}else{
p = (c + 24) - a;
}
int q;
if(d >= b){
q = d - b;
}else{
q = (d + 60) - b;
p = p - 1;
}
printf("%02d:%02d\n",p, q);
return 0;
}
在scanf中,我错误的输入了两个换行符号,导致输入后没有反应;在“ printf("%02d:%02d\n",p, q);语句中,“0” 的作用是确保输出的数字占两位,并在需要时用零填充。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 200/400 2/4 18/38
第三周 200/600 3/7 22/60
第四周 100/700 2/9 30/90
第五周 200/900 1/10 40/130
第六周 300/1200 1/11 40/170