一,基本概念
数据结构:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
算法(Algorithm):是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
二,线性结构
2.1线性表
线性表是线性的,把数据排成一条线组成。
- 对于同一个线性表,每一个数据元素的值虽然不同,但必须具有相同的数据类型。
- 数据元素之间具有一种线性的或“一对一”的逻辑关系。
- 第一个数据元素没有前驱,这个数据元素称为:开始节点;
- 最后一个元素没有后驱,这个元素称为:终端节点;
- 除第一个,和最后一个元素外,其他数据元素只有一个前驱和一个后驱。
- 线性表一般由顺序表和链表表示,应用于,栈,队列,字符串等。
顺序表
顺序表的定义:顺序表就是顺序储存的结构。在计算机内存中以数组的形式保存的线性表。顺序储存是指用一组地址连续的储存单元存放元素。
特点:
1.对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度为O(1), O(N)。
2.顺序表储存的数据在逻辑和内存中是按顺序的(也就是相邻的),但不代表数据是有序的。即顺序表不等于有序表。
3.储存密度高,但要预先分配内存,这可能造成浪费。
4.不便于插入和删除。
链表
由节点组成,方便插入和删除。节点由 指针和数据部分组成。
链表一般有带头结点,和不带头结点。其中带头结点的链表第一个结点不储存数据,不带头结点的链表第一个结点储存数据。
2.2堆栈(Stack)
堆栈是一种线性结构,是一种特殊的线性表。在计算机中有广泛的应用,比如:函数调用,递归,表达式求值等。
堆栈:具有一定约束的线性表——只能在一端做插入和删除。其中插入叫入栈,删除叫出栈。具有后进先出的特点。这有一点像羽毛球桶,放只能放在最上面,取也只能拿出最上面的那个。
堆栈的一般数据结构为(数组储存):
struct SNode {
ElementType *Data; /* 存储元素的数组,这是一个数组,根据需求定义 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
出栈和入栈可以穿插交替进行。
考试一般会有中缀表达式转换为后缀表达式。
2.3队列(Queue)
队列就是我们日常所见的排队了。
队列:具有一定操作约束的线性表——只能在一端插入,在另一端删除。其中插入叫入队,删除叫出队。具有先进先出的特点。
应用场所有:打印机缓存,后面树的层序遍历等。
三,树
3.1什么是树
树是基本数据结构的一种。也叫树状图。形状像是一颗倒挂的树。
特点:
1.空节点和一个节点也是一棵树。
2.节点的度:一个节点所含有的子结点的个数就是该节点的度
3.树的度:一棵树中最大的节点的度称为树的度。其中度为0的节点时是叶节点。
4.树的根:没有父节点的节点叫根。
3.2二叉树及储存结构
二叉树是度为2的树。二叉树的应用和种类都有很多。
二叉树的链表数据结构一般为:
typedef struct sNode *Tree;
struct sNode{
ElementType Data; /* 结点数据 */
Tree Left; /* 指向左子树 */
Tree Right; /* 指向右子树 */
};
3.3二叉树的遍历
二叉树的遍历有先序遍历,中序遍历,后序遍历和层序。
遍历规则是:
先序遍历: [根][左子树][右子树]
中序遍历:[左子树][根][右子树]
后序遍历:[左子树][右子树][根]
层序:从上到下从左到右依存遍历
其中左右子树用相同的规则。
3.4二叉搜索树
二叉搜索树也称二叉排序树或二叉查找树。
定义:
- 非空左子树的所有键值小于根结点键值
- 非空右子树的所有键值大于根节点键值
- 左右子树都是二叉搜索树
特点:
- 二叉搜索树的中序遍历是单调递增的。
- 二叉搜素树的n节点查找时间复杂度在:O(Log₂n):(平衡时,高度为Log₂n+1,为折半查找)到O(n):(完全不平衡)之间。
3.5平衡二叉树(ALV树)
定义:平衡二叉树:空树,或者任一节点左右子树高度差的绝对值不超过1,即 | BF(T) | <= 1
那么n(h)是高度为h的平衡二叉树的最小结点是:如下公式
特点:
- 平衡二叉树是二叉搜索树,具有二叉搜索树的特性。
- 平衡二叉树的n个节点查找效率为O(log₂n)
ALV树最复杂的是插入操作:因为插入节点可能会打破平衡,所以涉及平衡的调整:RR旋转,LL旋转,LR旋转,RL旋转。
3.6堆
这个堆不是堆栈。
堆是解决有优先级别的问题,比如计算机任务调度问题,优先解决的问题是优先级高的任务。也叫优先队列。
堆有最大堆和最小堆。
最大堆(最小堆)特点:
- 堆使用完全二叉树出储存。
- 任一结点的关键字是左右节点的最大值(最小值)
- 任意一条从根节点到叶结点的关键字路径都是降序的(升序的)
- 在定义的时候一般会定义哨兵。
- 排序有一种叫堆排序
3.7哈夫曼树与哈夫曼编码
哈夫曼树
哈夫曼树是带权路径长度(WPL)最小的二叉树,也叫最优二叉树。
带权路径长度(WPL)::设二叉树有n个叶子结点,每个叶子结点带有权值Wκ,从根结点到每个叶子结点的长度为lκ,则每个叶子结点的带权路径长度之和就是WPL=∑Wκ•lκ(n,i=1)。
特点:
- 没有度为1的节点
- n个叶子节点的哈夫曼树总共有2n-1个节点
- 哈夫曼树的任意非叶子节点的左右子树交换后仍是哈夫曼树
- 同一权值的哈夫曼树不唯一。
哈夫曼编码
使用哈夫曼树对计算机文件进行优化编码。
3.8集合及运算
B树
四,图(Graph)
4.1什么是图
- 表示“多对多”的关系。
- 包含:一组顶点:V(vertex)表示顶点集合。一组边:E(Edge)表示边集合。
- 无向边(v₁,v₂)∈E。有向边<v₁,v₂>∈E。
- 图(Graph):由一个非空的有限顶点集合v和有限集合边E组成
图特点:
- 是不考虑重边和自回路
- 非空,可以没有边但不能没有点
图有两种常用表示方法:邻接矩阵表示法和邻接表表示法
邻接矩阵表示法
邻接表表示法
4.2图的遍历
深度优先搜索(Depth First Search,DFS)
类似于树的先序遍历
先查找一个结点的下一个结点(多个结点中的任意一个),如果下一个结点有“没有经过的子结点”就继续向下,否则返回上一个结点在查找,直到返回起始结点。
广度优先搜索(Breadth First Search,BFS)
有点类似于树的层序遍历
查找起始结点所有相连的结点,押进栈,然后出栈找下一个结点的所有结点,并押进栈,直到栈为空。
最短路算法
迪杰斯特拉(Dijkstra)算法
弗洛伊德(Floyd)算法
4.3最小生成树问题
最小生成树(Minimum Spanning Tree):
普里姆(Prim)算法-让一棵树一点点长大
于 Dijkstra有一点像。
随便找一个根结点作为一个小树,然后找这颗小树相连的最小权重的节点,将他收到树中,直到所有节点收完为止。
克鲁斯卡尔(Kruskal)-将森林合并成树
将每个结点都看成是一棵树
每次就找权重最小的一边
将边链接的结点构成一棵树,且不成回路
4.4拓扑排序
AOV(Activity On Vertex)网络:(百科)在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系。这样的有向图为顶点表示活动的网,我们称为AOV网(Activity On Vertex Network)。
特点:
- 拓扑排序不是唯一的。
关键路径问题
AOE(Activity On Edge):网络,一般用于安排项目的工序
五,排序
平均效率 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 | |
---|---|---|---|---|---|
冒泡排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |
插入排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |
选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |
快速排序 | O(n log n) | O(n log n) | O(n²) | O(log n)~O(n) | 不稳定 |
堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | 不稳定 |
归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
希尔排序 | O(n log n) ~ O(n²) | O(n¹•³) | O(n²) | O(1) | 不稳定 |
六,散列
结语
没得写完,以后再说吧!