一、指针操作
C语言支持两种数据集合:结构和数组。
作为函数参数的指针;
按引用调用传递参数;
int f1(int a[]); <==> int f1(int *a); (等价)
泛型指针(void*)
二、递归
》基本递归
一种强大的方法,允许一个问题以其自身越来越小的形式来定义自己。在计算机可学领域中,我们通过使用递归函数来解决带有递归性质的问题,也就是用函数调用自身。
》尾递归
递归的一种形式,这里编译器会为此产生优化的代码。大多数现代的编译器能够识别尾递归。为此,只要条件允许我们应该利用这个特性。
A、在基础递归中,函数的调用类似于
这种递归调用有点象栈的先进后出,后进先出。栈包含函数调用的信息。
当C程序中调用了一个函数时,栈中会分配一块空间来保存与这个调用相关的信息。每一个调用都被当做是活跃的。栈上的那块存储空间成为活跃记录,或者称为栈帧。栈帧由5个区域组成:输入参数、返回值空间、计算表达式时用到的临时存储空间、函数调用时保存的状态信息以及输出参数。
B、尾递归
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
四、链表
五、堆栈
栈和队列
a、栈的一个显著特征是它按照后进先出(LIFO)的方式存储和删除元素。
类似于链表,可以通过链表特殊情况来处理(头进头出);
b、队列也是用链表来处理,
六、哈希表
桶的概念。
1、哈希表支持一种最有效的检索方法:散列。从根本上来说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素。哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表。哈希函数每次接受一个键将返回与键相对的哈希编码或哈希值。键的数据类型可能多种多样,但哈希值的类型只能是整形。
2、有链式哈希表、开地址哈希表等等。
链式哈希表:将数据存储在“桶”(bucket)中的哈希表。每个“桶”都是一个链表,且链表的容量能够随着冲突的增加而增大。
开地址哈希表:将数据存储在表本身中,而不是“桶”中的哈希表。它通过各种探查方法来避免冲突问题。
3、哈希表的应用
数据库系统、符号表、标签缓冲区、数据字典、关联数组等等。
数据库系统主要用来优化两种数据访问方法:顺序访问和随机访问。哈希表是高效的随机访问方法的一个重要组成部分,因为它能在固定时间内定位数据。
七、树
树的应用包括霍夫曼编码、用户界面、数据库系统、表达式处理、人工智能、事件调度、优先级队列等等。
树的周游算法一般有四种:先序遍历(前序遍历)、中序遍历、后序遍历和层级遍历。
先序遍历:首先访问它的根结点,然后是左子结点,最后是右子结点。由于按照从左到右的方式依次遍历各个子树,因此以相同的方式将左子结点和右子结点当做新的子树的根。先序遍历是按照深度优先的方式遍历结点的。
中序遍历:首先访问左子结点,然后是根结点,最后是右子结点。由于按照从左到右的方式依次遍历各个子树,因此相同的方式将左子结点和右子结点当做新的子树的跟。
后续遍历:首先访问左子结点,然后是右子结点,最后是根结点。由于按照从左到右的方式依次遍历各个子树,因此以相同的方式将左子结点和右子结点当做新的子树的跟。
层级遍历:首先方位数的根,然后依次向下层处理,按照从左到有的顺序访问每层的结点。层级遍历运用了广度优先的策略。
八、堆和优先队列
九、图
图由两种类型的元素组成:顶点和边。顶点代表对象,边则建立起对象之间的关系或关联。
图包含边(u,v), 则称顶点v与定点u邻接。(注意是后者v与前者u邻接)。如果一幅图中的每一个顶点都与其他顶点相邻接,则称这幅图是完全图。
关联是顶点与边之间的关系。在有向图中,边(u,v)从顶点u开始关联到v。在有向图中,顶点的入度(in-degree)指的是以该顶点为终点的边的数目。而顶点的出度(out-degree)指的是从该顶点为起点的边的数目。在无向图中,边(u,v)与顶点u和v相关联,而顶点的度就是与该顶点相关联的边的数目。
搜索方法
a、广度优先搜索
广度优先搜索在进一步探索图中的顶点之前优先访问当前顶点的所有邻接结点。这种查找方法在很多应用中都非常有用,包括找出最小生成树以及最短路径问题。
b、深度优先搜索
深度优先搜索在搜索过程中每当访问到某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点。因而,这种搜索将尽可能深地持续探索,直到无法继续为止。这种策略使得深度优先搜索在很多应用中非常有用,包括环检测以及拓扑排序。