第 1 章 绪论

第 1 章 绪论

敬告读者

本系列教程是面对零基础学习“数据结构”的读者,包括但不限于计算机相关专业、其他各种专业开始学习数据结构的大学生。

本系列教程可以作为学习的入门读物,也可以作为备考计算机相关专业“教辅”(包括“跨考”和本专业的同学)。

本系列教程以作者在学习、研究和开发实践为基础,力图将数据结构中的有关知识阐述清楚,并结合基础知识适时拓展,从而让读者能够更深入地理解该知识的来龙去脉和实践应用。

本系列文章发布之后,会不定期进行修改,敬请读者关注。

1.1 什么是数据结构

想象一下你的书桌:书本随意堆放,文具散落各处,想找支笔都要翻半天。如果换成带标签的笔筒、分层的书架、按字母排列的文件柜呢?找东西瞬间变得轻松愉快!数据结构,就是计算机世界里这套神奇的“收纳整理术”。

简单来说,数据结构是计算机存储、组织和管理数据(信息)的方式。 就像不同的物品需要不同的收纳工具(衣服用衣柜,文件用文件夹),不同类型的数据和不同的使用需求,也决定了计算机要选择最合适的“数据容器”和“操作规则”。

数据结构作为一门学问或者研究方向,其核心目标只有一个:让计算机更高效地工作!

  • 找得快: 快速找到需要的数据(就像从索引清晰的词典里查单词)。
  • 存得好: 节省宝贵的内存或硬盘空间(就像把衣物卷起来收纳节省衣柜空间)。
  • 改得顺: 方便地添加新数据、删除旧数据或修改现有数据(就像在活页笔记本里增减页面)。

如果用严谨的语言阐述什么是数据结构,此处引用严蔚敏教授的《数据结构》中的定义:

数据结构(Data Structure)是相互之间存在一种或多种特定关系的数据元素的集合。换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系(严蔚敏)。

:本系列文章中,将在多处引用严蔚敏教授的《数据结构》中的表述,所参考版本是人民邮电出版社 2015 年 2 月第 2 版(如图 1.1.1)。引用标识为所引用文字后面加括号标注,如上所示。

图 1.1.1 严蔚敏教授的《数据结构》封面

严蔚敏(1938年4月—2024年12月10日),女,汉族。清华大学计算机系教授,长期从事数据结构教学和教材建设,同吴伟民合作编著的《数据结构》曾获“第二届普通高等学校优秀教材全国特等奖”和“1996年度国家科学技术进步奖三等奖”。2024 年 12 月10 日 14 时 22 分,严蔚敏去世,享年 86 岁。

严教授长期致力于数据结构的教学与研究,是中国最早一批开设数据结构课程的先驱者之一,为国内的数据结构教育奠定了坚实基础。
在这里插入图片描述

1.2 逻辑结构和存储结构

数据结构包括逻辑结构和存储结构两个层次。

首先,通俗地理解逻辑结构和存储结构的含义。

以图书馆为例,它必须要确定对图书的分类方法(是按学科还是按作者分类),还要为读者提供查找方法,比如很早的时候图书馆是索引卡查找图书,后来是通过计算机检索,当然还要制定借阅规则。所有这些,所关注的是数据元素(对图书馆而言就是图书和读者)之间的抽象关系,是概念层面的设计蓝图。除此之外,图书馆中还必须确定书架怎么摆放、每本书在书架上的具体位置(索书号对应哪个架子的第几层)、索引卡柜放在哪里、计算机和服务器放哪等等。这些则是是物理实现层面的具体施工,即数据元素及其关系在计算机内存(或磁盘)中的实际存放方式。

1.2.1 逻辑结构

数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的(严蔚敏)。它定义了“数据是什么”以及“数据之间有什么关系”,关注点在于元素间的逻辑关系(前驱/后继、父子、连接等),要解决的核心问题是如何组织数据以反映现实世界的实体及其联系。

逻辑结构的常见类型包括:

  • 集合:最松散的结构。元素间除了“同属一个集合”外,没有其他特定关系。例如:一个班级里所有学生的名字构成的集合。
  • 线性结构:元素之间存在一对一的顺序关系。像一条线串起来。这种结构的特点是:有且仅有一个开始元素(第一个元素/头元素)和一个结束元素(最后一个元素/尾元素);除首尾元素外,每个元素有且仅有一个直接前驱和一个直接后继。例如后续将介绍的数组、链表、栈、队列、字符串均属于线性结构。
  • 树形结构:元素之间存在一对多的层次关系。像一棵倒过来的树。其特点是有且仅有一个根结点;除根结点外,每个结点有且仅有一个父结点;一个结点可以有零个或多个子结点;没有子结点的结点称为叶结点。例如文件系统目录树、公司组织结构图、家谱(族谱)、HTML文档对象模型(DOM)等均属于树形结构。
  • 图状结构(网状结构):元素之间存在多对多的任意关系。像一张错综复杂的网。其特点是任何两个元素之间都可能存在关系(边/连接);结点之间的关系是任意的,没有像树那样的层次限制。例如交通路线图(城市是结点,道路是边)、社交网络(人是结点,好友关系是边)、电路网络等均属于图状结构。

1.2.2 存储结构(物理结构)

存储结构,也称为物理结构,描述数据元素及其逻辑关系在计算机存储器(主要是内存)中的具体存放方式(表示方法)。它定义了“数据怎么存”。关注点在于数据元素在内存中的物理位置(地址)以及如何利用这些位置信息来表示实现逻辑关系。要解决的核心问题是如何在有限的、线性的内存地址空间中高效地存放数据和表达其逻辑关系。

存储结构的类型有两种:

  • 顺序存储结构:在内存中分配一块连续的存储空间,按逻辑顺序依次存放数据元素。逻辑关系(如前驱后继)通过元素的物理位置相邻性来隐含表示。
  • 链式存储结构:在内存中分配不连续的存储单元存放数据元素。每个元素(称为结点)不仅包含数据本身(数据域),还包含一个或多个指针域,用于显式存储指向其逻辑关系元素(如后继结点、子结点、邻接结点)的内存地址。

在后续内容中,将详细阐述这两种存储结构的特点,此处暂且有上述基本了解即可。

下表对比了逻辑结构与存储结构的异同。

特性逻辑结构存储结构(物理结构)
本质概念模型,描述数据元素间的抽象关系。实现模型,描述数据元素在内存中的具体存放。
关注点数据元素之间的关系 (一对一、一对多等)。数据元素在内存中的位置和关系表示方法。
层次抽象层,独立于计算机和语言。物理层,依赖于计算机的存储特性和语言实现。
设计目标如何组织数据以反映现实世界的逻辑关联。如何在内存中高效(空间+时间)地存储和访问数据。
可变性相对稳定,取决于问题本身的性质。可以有多种选择,根据需求(性能、空间)权衡选择。

1.2.3 二者的关系

逻辑结构定义了数据应该呈现的最终形态和关系,存储结构提供了具体的方法和技术,从而在物理内存中实现这种形态和关系。选择哪种存储结构是为了更好地服务于逻辑结构的需求。

同一种逻辑结构可以用多种不同的存储结构来实现。例如线性表(逻辑结构)可以用顺序存储结构(数组),也可以用单链表、双链表、循环链表等链式存储结构。

选择的哪种存储结构,将直接决定对数据进行基本操作(查找、插入、删除、修改、遍历)的效率(第 2 章将重点研究效率问题)。例如在数组(顺序存储)实现的线性表中,随机访问元素效率就很高,但在中间插入/删除元素的操作效率就很低,因为要移动元素。

在设计数据结构时,先分析数据的本质关系(确定逻辑结构),然后分析对该数据最常进行的操作是什么(查找为主还是频繁地进行插入/删除操作,是否排序等),最后根据效率要求和内存限制,选择合适的存储结构来实现该逻辑结构。

对于数据的逻辑结构和存储结构,读者暂有如下认识,随着后续学习,将不断深化对二者的理解。

  • 逻辑结构是“是什么”和“有什么关系”:它描绘了数据元素之间抽象的概念性关联(线性、树形、图状等),是设计数据的蓝图。
  • 存储结构是“怎么存”和“关系怎么表示”:它规定了数据元素及其关系在计算机内存中的具体物理实现方式(连续存放、指针链接等),是建造数据的施工方案。
  • 关系是目标与手段:逻辑结构是我们要达到的组织目标,存储结构是我们用来实现这个目标的具体技术手段。同一个目标(逻辑结构)可以用不同的技术(存储结构)来实现,而选择哪种技术会极大影响数据操作的效率(速度、空间)。理解它们的区别和联系,是高效设计和应用数据结构的基础。

1.3 算法

1.3.1 初识算法

算法(Algorithm)是为了解决某类问题而规定的一个有限长的操作序列(严蔚敏),本质上就是计算机做事“操作说明书”,它定义了一个清晰的、有限的、确定的步骤序列,用于解决一个特定的问题或完成一项明确的任务。

一个算法必须满足以下五个重要特性(严蔚敏)。

  • 有穷性。一个算法必须总是在执行有穷步后结束,且每一步都必须在有穷时间内完成。
  • 确定性。对于每种情况下所应执行的操作,在算法中都有确切的规定,不会产生二义性,使算法的执行者或阅读者都能明确其含义及如何执行。
  • 可行性。算法中的所有操作都可以通过已经实现的基本操作运算执行有限次来实现。
  • 输入。一个算法有零个或多个输入。当用函数描述算法时,输入往往是通过形参表示的,在它们被调用时,从主调函数获得输入值。
  • 输出。一个算法有一个或多个输出,它们是算法进行信息加工后得到的结果,无输出的算法没有任何意义。当用函数描述算法时,输出多用返回值或引用类型的形参表示。

评价算法好坏的核心标准是效率,主要体现在两方面:

  • 时间效率(时间复杂度):算法执行需要多少时间?我们关心它随着问题规模(比如数据量)增大,耗时的增长趋势(是线性增长?指数级爆炸)。
  • 空间效率(空间复杂度:算法执行需要多少内存空间?同样关心其随问题规模增长的趋势。

以上两方面的评估方法,将在第 2 章详述。

1.3.2 数据结构和算法的关系

可以毫不夸张地说,数据结构和算法是计算机程序的“灵魂”与“骨架”,它们相互依赖,共同决定了程序的效率和能力。

  1. 数据结构是算法的基础和操作对象:任何算法都需要处理数据。这些数据不是散乱无章的,而是按照某种数据结构组织起来的。算法能对数据做什么,很大程度上取决于它操作的数据结构提供了哪些基本操作。例如:要在一个数据结构中频繁地“在任意位置插入”数据,那么链表通常比数组更高效。所以,选择合适的数据结构是设计高效算法的前提,没有脱离数据结构而存在的算法。算法总是作用于特定的数据结构之上。
  2. 算法是发挥数据结构效能的关键:算法定义了如何高效地使用数据结构来完成特定任务。相同的数据结构,不同的算法,效率天差地别,例如,同样是在一个有序数组(数据结构)中执行查找操作,用顺序查找(算法)可能很慢,而用二分查找(算法)就比顺序查找快。算法通过调用数据结构提供的操作来实现更复杂的逻辑,算法的设计也受限于数据结构的特性。。

数据结构和算法的关系的经典表述,是瑞士计算机科学家尼古拉斯·沃斯提出:程序 = 数据结构 + 算法,这精辟地概括了两者的核心地位和密不可分的关系。

|在这里插入图片描述
|在这里插入图片描述
|在这里插入图片描述

图 1.3.1 《算法+数据结构=程序》

尼古拉斯·埃米尔·沃思(德语:Niklaus Emil Wirth,1934年2月15日—2024年1月1日),瑞士计算机科学家。他是好几种编程语言的主设计师,如:Algol W、Modula、Pascal、Modula-2、Oberon,是 Euler 语言的发明者之一。1984 年他因发展了这些语言而获图灵奖。他的文章《Program Development by Stepwise Refinement》被视为软件工程中的经典之作。他写的一本书的书名《Algorithms + Data Structures = Programs》(《算法+数据结构=程序》)是计算机科学的名句。

数据结构和算法的目的都是为了高效地解决实际问题,数据结构提供了高效存储和管理数据的基础,算法则提供了利用这些数据高效解决问题的方法。研究新的高效算法常常需要设计新的数据结构来支撑它。反过来,设计出强大的新数据结构,也会催生出一系列利用其特性的新算法。

理解数据结构和算法及其关系,是打开计算机科学大门、编写优秀程序的基石。就像优秀的厨师既懂得选择优质的食材(数据),也懂得使用合适的厨具(数据结构),更精通烹饪的技巧(算法),才能做出美味佳肴(高效的程序)。

1.4 关于编程语言

数据结构和算法,一般可以使用自然语言描述,也可以使用编程语言表达。

自然语言(像中文、英文等日常语言 )能以通俗易懂、贴近人类思维的方式,阐述数据结构和算法的逻辑。但是,用自然语言描述的数据结构和算法,难以精准体现复杂逻辑细节,无法直接用于程序执行,比较适合理论讲解、需求沟通等。用编程语言则能精准、形式化地实现数据结构和算法的描述,让逻辑可被计算机执行。

从理论上讲,任何编程语言都能够描述数据结构和算法,“最好用面向对象的方法,比如用 C++ 语言的类描述比较方便、有效,但本课程大都在大学低年级开设,用 C 语言的描述方法更符合学生的实际情况。另外,由于实际问题千变万化,数据模型和算法也形形色色,因此(抽象)数据类型的设计和实现,就不可能像基本数据类型那样规范和一劳永逸。本书所讨论的数据结构及其算法主要是面向读者的,故采用介于伪码和 C 语言之间的类 C 语言作为描述工具。这使得数据结构与算法的描述与讨论简明清晰,不拘泥于 C 语言的细节,又容易转换成 C 或 C++ 程序”(严蔚敏)。

一下内容参考自严蔚敏教授的教材:

(1)预定义常量

#define OK 1    
#define ERROR 0
#define OVERFLOW - 2
//Status 是函数返回值类型,其值是函数结果状态代码
typedef int Status;

(2)用 typedef 定义类型

  • 为基本数据类型定义新的类型名,即取个别名。

    typedef int Status;    //Status 是 int 的别名
    
  • 自定义数据类型,例如自定义一个复数:

    typedef struct
    {
        float Realpart;  //实部
        float Imagepart;    //虚部
    }Complex;    //类型名称
    

(3)函数格式

函数类型 函数名称(参数列表){
    //算法说明
    语句序列
}//函数名

在形参表中,以 & 开头的参数即引用参数。传递引用给函数与传递指针的效果一样,形参变化实参也发生变化,但引用使用起来比指针更方便、高效。

(4)内存的动态分配与释放

  • 分配空间:指针变量 = new 数据类型; ,例如:

    char *pc = new char;         //申请一段空间用来存储char类型,内存中没有初始值
    int *pi = new int(10);       //申请一段空间存储int类型数据,初始值为10
    double *pd = new double();   //申请一段空间存储double类型的数据,默认初始值为0
    

    也可以用 new 数据类型[数组长度]; 创建数组对象,例如:

    int *pi = new int[10]();   //后面的小括号可以有,但不可以指定任何初始值;初始值为 0
    char *pc = new char[10];   //没有提供初始值
    double* pd = new double[0];  //长度为 0 的 double 类型数组
    

    也可以使用 C 语言中的定义方法,例如:

    char *str
    str = (char *) malloc(15)
    

    malloc() 内的参数是需要动态分配的字节数,而不是可以存储的元素个数!

    • 当动态分配内存时,存储的是字符型数据,每个元素 1 字节,所以字节数刚好等于需要存储的元素个数(字符数 +1);

    • 如果存储的是整型或浮点型数据,字节数等于“需要存储的元素个数 × 一个元素的字节数”,代码格式:

      type *var_name = (type*)malloc(sizeof(type)*num);
      
  • 释放空间:delete 指针变量

    删除指针变量指向的对象,释放内存空间。

    在 C++ 中,如果要释放数组对象,格式为:delete []指针名 。但,算法中,不强调 []

(5)赋值语句:

  • 简单赋值 变量名 = 表达式;
  • 串联赋值 变量名 1 = 变量名 2 = … = 变量名 n = 表达式;
  • 成组赋值 (变量名 1, ..., 变量名 n) = (表达式 1, ..., 表达式 n);
  • 结构赋值 结构名 1 = 结构名 2; 结构名 = (值 1, 值 2, ..., 值 n);
  • 条件赋值 变量名 = 条件表达式 ?表达式 T:表达式 F;
  • 交换赋值 变量名 1 <--> 变量名 2;

(6)选择语句:

  • 条件语句 1 if (表达式) 语句;

  • 条件语句 2

    if (表达式) 语句;
    else 语句;
    
  • 开关语句

    switch (表达式){
        case1: 语句序列 1; break;
        case2: 语句序列 2; break;
        ... 
        case 值n: 语句序列 2; break;
        default: 语句序列 n+1;
    }
    

(7)循环语句:

  • for 语句 for (表达式 1; 条件;表达式 2) 语句;

  • while 语句 while (条件) 语句;

  • do-while 语句

    do {
        语句序列;
    }while (条件);
    

(8)结束语句:

  • 函数结束语句

    return 表达式;
    return;
    case 或循环结束语句 break;
    异常结束语句 exit (异常代码);
    

(9)输入输出语句使用 C++ 流式输入输出的形式:

  • 输入语句 cin >> 变量1 >> … >> 变量n;
  • 输出语句 cout << 表达式1 << … << 表达式n;

(10)基本函数:

  • 求最大值 Max(表达式 1, ..., 表达式 n)
  • 求最小值 Min(表达式 1, ..., 表达式 n)

建议读者理解上述基本语法,以便能理解后续相关代码的含义。

1.5 常用的数学知识

在后续各章节的内容中会经常用到一些数学知识,为了方便读者查阅,此处列出常用的内容。

1 指数运算
xaxb=xa+bxaxb=xa−b(xa)b=xabxn+xn=2xn≠x2n2n+2n=2⋅2n=2n+1 \begin{split} &x^ax^b=x^{a+b} \\&\frac{x^a}{x^b}=x^{a-b} \\&(x^a)^b=x^{ab} \\&x^n+x^n=2x^n\neq x^{2n} \\&2^n+2^n=2\cdot2^n=2^{n+1} \end{split} xaxb=xa+bxbxa=xab(xa)b=xabxn+xn=2xn=x2n2n+2n=22n=2n+1

2 对数

在本书中,除非特别声明,所有对数都是以 2 为底。
log⁡ab=log⁡cblog⁡ca,(c>0)log⁡(ab)=log⁡a+log⁡blog⁡(ab)=log⁡a−log⁡blog⁡(ab)=blog⁡alog⁡1=0, log⁡2=1, log⁡1024=10 \begin{split} &\log_ab=\frac{\log_cb}{\log_ca},(c\gt0) \\&\log(ab)=\log{a}+\log{b} \\&\log(\frac{a}{b})=\log{a}-\log{b} \\&\log(a^b)=b\log{a} \\&\log1=0,~\log2=1,~\log1024=10 \end{split} logab=logcalogcb,(c>0)log(ab)=loga+logblog(ba)=logalogblog(ab)=blogalog1=0, log2=1, log1024=10

3 求和

  • 求和公式

    • ∑i=lu1=1+1+⋯+1⏟u−l+1次=u−l+1\sum\limits_{i=l}^u1=\underbrace{1+1+\cdots+1}_{u-l+1次}=u-l+1i=lu1=ul+11+1++1=ul+1l,ul,ul,u 是整数边界,l≤ul\le ulu);∑i=1n=n\sum\limits_{i=1}^n=ni=1n=n
    • ∑i=1ni=1+2+⋯+n=n(n+1)2≈12n2\sum\limits_{i=1}^ni=1+2+\cdots+n=\frac{n(n+1)}{2}\approx\frac{1}{2}n^2i=1ni=1+2++n=2n(n+1)21n2
    • ∑i=1ni2=12+22+⋯+n2=n(n+1)(2n+1)6≈13n3\sum\limits_{i=1}^ni^2=1^2+2^2+\cdots+n^2=\frac{n(n+1)(2n+1)}{6}\approx\frac{1}{3}n^3i=1ni2=12+22++n2=6n(n+1)(2n+1)31n3
    • ∑i=1nik=1k+2k+⋯+nk≈1k+1nk+1,(k≠−1)\sum\limits_{i=1}^ni^k=1^k+2^k+\cdots+n^k\approx\frac{1}{k+1}n^{k+1},(k\ne-1)i=1nik=1k+2k++nkk+11nk+1,(k=1)
    • ∑i=0nai=1+a+a2+⋯+an=an+1−1a−1,(a≠1)\sum\limits_{i=0}^na^i=1+a+a^2+\cdots+a^n=\frac{a^{n+1}-1}{a-1},\quad(a\ne1)i=0nai=1+a+a2++an=a1an+11,(a=1)∑i=0n2i=2n+1−1\sum\limits_{i=0}^n2^i=2^{n+1}-1i=0n2i=2n+11
    • ∑i=1nlog⁡i≈nlog⁡n\sum\limits_{i=1}^n\log i\approx n\log ni=1nloginlogn
  • 求和乘法法则

    • ∑i=lucai=c∑i=luai\sum\limits_{i=l}^uca_i=c\sum\limits_{i=l}^ua_ii=lucai=ci=luai
    • ∑i=lu(ai±bi)=∑i=luai±∑i=lubi\sum\limits_{i=l}^u(a_i\pm b_i)=\sum\limits_{i=l}^ua_i\pm\sum\limits_{i=l}^ub_ii=lu(ai±bi)=i=luai±i=lubi
    • ∑i=luai=∑i=lmai+∑i=m+1uai,(l≤m<u)\sum\limits_{i=l}^ua_i=\sum\limits_{i=l}^ma_i+\sum\limits_{i=m+1}^ua_i,\quad(l\le m\lt u)i=luai=i=lmai+i=m+1uai,(lm<u)
    • ∑i=lu(ai−ai−1)=au−al−1\sum\limits_{i=l}^u(a_i-a_{i-1})=a_u-a_{l-1}i=lu(aiai1)=aual1

4 取整

向下和向上取整。向下取整:⌊x⌋\lfloor x\rfloorx ;向上取整:⌈x⌉\lceil x\rceilx

  • x−1<⌊x⌋≤x≤⌈x⌉<x+1x-1\lt\lfloor x\rfloor\le x\le\lceil x\rceil\lt x+1x1<xxx<x+1
  • 对于 x∈R,n∈Nx\in\mathbb{R},n\in\mathbb{N}xR,nN⌈x+n⌉=⌈x⌉+n\lceil x+n\rceil=\lceil x\rceil+nx+n=x+n⌊x+n⌋=⌊x⌋+n\lfloor x+n\rfloor=\lfloor x\rfloor+nx+n=x+n
  • ⌊n2⌋+⌈n2⌉=n\lfloor\frac{n}{2}\rfloor+\lceil\frac{n}{2}\rceil=n2n+2n=n
  • ⌈log⁡(n+1)⌉=⌊log⁡n⌋+1\lceil\log(n+1)\rceil=\lfloor\log n\rfloor+1log(n+1)⌉=logn+1

1.6 关于 408

1.6.1 什么是 408

学习本教程的,或许有一部分是准备考研的同学,在计算机专业课的研究生入学考试中,自 2009 年开始,教育部推出的“统考卷”或“全国卷”,用以区分某些学校的“自命题卷”,其正式名称是“计算机学科专业基础综合考试”,科目代码是 408,通常用此代码作为此考试的简称。时至如今,已有越来越多的高校在计算机专业以及其他相关专业(比如软件工程、人工智能等)的“初试”选择 408 。可以预知,这是大势所趋。所以,在此介绍一下 408 的相关信息。

408 的基本目标和对考生的要求在历年的“考试大纲”中表达的非常清晰,即:

计算机学科专业基础综合考试是为高等院校和科研院所招收计算机科学与技术学科的硕士研究生而设置的具有选拔性质的联考科目,其目的是科学、公平、有效地测试考生掌握计算机科学与技术学科大学本科阶段专业知识、基本理论、基本方法的水平和分析问题、解决问题的能力,评价的标准是高等院校计算机科学与技 术学科优秀本科毕业生所能达到的及格或及格以上水平,以利于各高等院校和科研院所择优选拔,确保硕士研究 生的招生质量。(选自 408 考试大纲)

分析历年 408 的试卷可知,其考试形式和试卷结构比较稳定:

  • 试卷满分为 150 分,考试时间为 180 分钟。

  • 试卷内容结构:

    科目分值
    数据结构45
    计算机组成原理45
    操作系统35
    计算机网络25
  • 试卷题型结构:

    • 单项选择题 80 分(40 小题,每小题 2 分);
    • 综合应用题 70 分。

这种稳定的试卷结构,便于考生复习。

其中,“数据结构”的题目分布一般是:

  • 单项选择题:第1题 ~ 第11题,总计 22 分(有的年份少 1 个题目,即少 2 分);
  • 综合应用题:第 41 题、第 42 题,总计 23 分(如果选择题是 20 分,则此处总计为 25 分)。

本教程适用于 408 和“自命题”的基础知识复习阶段。

1.6.2 复习建议

考研复习过程与曾经的高考复习不同,高考复习一般在“有严密组织要求和规划的集体”中进行的,而考研复习更强调备考者的“自主性”和“自我管理”,这对于很多摩拳擦掌准备考研的同学而言是较大挑战。从历年经验来看,很多同学也正是缺乏“自主性”和“自我管理”,要么半途而废,要么功败垂成。因此,凡是开始阅读本书,有志于考研的同学,不仅要确立明确的目标,还要在复习过程中严格要求自己,“前途是光明的,道路是曲折的”,唯有百折不挠、持之以恒,才能金榜题名。

在复习中,除了精神上斗志昂扬、信心百倍之外,运用科学的复习方法也是必不可少的。以下内容是作者多年指导学生的经验总结,供读者参考。

  • 理解基础知识,弄懂其来龙去脉。本书内容覆盖“考试大纲”所要求的全部“考点”,读者在复习中,务必理解每个基本概念的含义,并能主动通过总结归纳建构起知识结构。

  • 勤思考,多动笔。在复习过程中,除了听课、看书之外,要不断将自己的理解与书中所述进行对照,从中找出偏差并给予纠正,而不是简单地“全盘接受”、“死记硬背”。

    • 某些结论的推导过程要亲自动笔推导;
    • 不论例题还是习题都要亲自动笔计算;
    • 不论是读书还是听课,都要动笔做笔记、勾画重点和难点,及时记录疑问;;
    • 每学完一个单元都要动笔总结,形成完整的知识结构。
  • 不放过任何疑问。在复习过程中,经常会遇到或大或小的疑问,当头脑中出现了“为什么”之后,一定不能用“就是这样规定的”、“记住这个结论会做题就行”等类似的理由将疑问放过。疑问不论大小,都是理解知识“更上一层楼”的阶梯,因此务必严肃对待,不能轻易放过。如何解决疑问?以下三个方法供读者参考:

    • 方法 1:利用大模型。作为学习“计算机科学与技术”的读者,一定要善于使用最新的科技产品,AI 技术能够帮助读者提高学习效率和效果。并且,在复习中如果掌握了使用大模型的方法,也会有益于将来的工作。

    • 方法 2:带着疑问重读书中对相关内容的讲述。有的疑问是由于遗忘或理解不深等原因造成的,那么,再次学习则因目标明确、注意力集中,其效果通常好于第一遍学习。所谓“书读百遍其义自见”,在这里可以借用。

    • 方法 3:向同学或者老师请教。如果自己能够将疑问清晰准确地表达出来,也可以向同学、老师请教,但是这里特别提醒读者,不要将题目直接呈现在被请教者面前,“这个题目我不会做,请问怎么做”,这种求助方式于己无效。因为对方的回复,不是自己思考的结果(是对方思考的结果),自己只是“成品”的欣赏者,却误以为也具有了同样的“创建成品的能力”。正确的做法是表达自己的思路,请对方帮助甄别该思路是否有错误,若有将如何改正。

每个读者也都有特殊的学习习惯,以上方法仅供参考。总而言之,希望读者能够以科学高校的方法进行复习,并达成较高的复习效果。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CS创新实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值