社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
码字不易,喜欢请点赞!!!
1.数据结构基础
2.线性表(顺序存储、链式存储)
3.栈
4.队列、循环队列
5.串
6.树
节点的度:节点的分支数目
树的度:树内各个节点的度的最大值
叶节点、终端节点:度为0的点
树的深度:树中节点的最大层次
二叉树:n个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根节点和两颗互不相交、分别称为根节点的左子树和右子树的二叉树组成。
二叉树的5种形态:
满二叉树:
完全二叉树
二叉树的性质
二叉树的第i层,最多有2i−1结点
深度为k的二叉树,最多有2k−1个节点
具有n个结点的完全二叉树的深度为[log2n]+1([x]表示对x下取整)
二叉树T,叶子节点数为n0,度为2的节点数为n2,则n0 = n2 + 1
因为节点数n = n0 + n1 + n2 = 2n2 + n1 + 1
所以:n0 = n2 + 1
对于完全二叉树的节点i:
二叉树的存储
一维数组存储:使用一维数组按照顺序存储,对于不存在的节点使用空来占位
二叉链表:lchild+data+rchild形式
二叉树的遍历:前序遍历、中序遍历、后序遍历、层序遍历(逐层遍历)
已知前序和中序,可以确定一颗二叉树
已知后序和中序,可以确定一颗二叉树
已知前序和后序,不可以确定一颗二叉树
树、森林、二叉树的转换
树转换成二叉树
1.加线:兄弟节点之间加一条线
2.去线:对每个节点只保留第一个子节点的连线,删除其他子节点的连线
3.层次调整:第一个子节点为左孩子,兄弟节点转成第一个子节点的右孩子
eg:
#森林由多棵树组成,将森林中每一颗树都视为兄弟,按照兄弟的办法来处理
1.将每棵树转成二叉树
2.将后面的树的根节点作为前面的树的根节点的右孩子
eg:
#树转成二叉树的逆过程
1.加线:左孩子的所有右孩子,与左孩子的父节点连接起来。
2.去线:删除原二叉树中的所有右孩子连线。
3.层次调整:旋转
eg:
#如果根节点有右孩子,则是森林,没有孩子,则是一棵树
1.先将根节点的右孩子线删除,拆成多颗二叉树
2.然后对每个二叉树执行拆分成树的操作
eg:
树与森林的遍历
树的遍历:先根遍历、后根遍历
森林的遍历:前序遍历、后续遍历
前序遍历结果:ABCDEFGHJI
后序遍历结果:BCDAFEJHIG
哈夫曼树
简介
1.节点的带权路径:节点到根之间的路径长度与节点权值的乘积
2.树的带权路径:树中所有节点的带权路径之和
3.哈夫曼树:带权路径长度WPL最小的二叉树,称为哈夫曼树,也叫最优二叉树
二叉树a的WPL=51+152+403+304+104=315
二叉树b的WPL=53+153+402+302+102=220
这个结果意味着,如果有10000个学生需要计算,那么二叉树a的判断方法需要计算31500次,而二叉树b的方法需要计算22000次。
7.图
定义
无向边:顶点之间没有方向,称这条边为无向边,用无序偶对(vi,vj)来表示
有向边:顶点之间有方向,称这条边为有向边,也称为弧,用有序偶对<vi,vj>来表示,如果图中任意两个顶点的边都是有向边,则称该图为有向图,要区分开弧尾vj和弧头vi
无向图:如果任意两个顶点之间都存在边,则称该图为无向完全图,含有n个顶点的无向完全图有n(n−1)/2条边。
有向图:如果任意两个顶点间都存在方向互为相反的两条弧,则称为有向完全图。含有n个顶点的有向完全图有n(n−1)条边。
连通图:无向图中,如果两个顶点之间有路径,说明两顶点是连通的,如果对于图中任意两个顶点都是连通的,则称该无向图是连通图。
极大连通子图称为连通分量:需要是1.子图;2.子图是连通的;3.连通子图含有极大顶点数;4.具有极大顶点数的连通子图包含依附这些顶点的所有边。
度:无向图顶点的边数叫度,有向图的顶点分为出度和入度。
生成树、森林:无向图中连通且n个顶点有n-1条边叫生成树;有向图中一个顶点入度为0,其余顶点入度为1称为有向树;一个有向图由若干个有向树构成生成森林。
图的存储结构
由于图的结构比较复杂,任意两点之间都可能存在联系,因此不能用简单的顺序存储结构来表示。
邻接矩阵
邻接矩阵的存储方式:两个数组来表示图;
一个一维数组存储图中顶点的信息;
一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。
临近矩阵的问题:对边数相对顶点数较少的图,这种结构是对存储空间的极大浪费,太稀疏。
邻接表:将数组与链表结合起来
无向图:
有向图:
带权有向图:
在有向图中,邻接表是有缺陷的,关心了出度问题,要想知道入度,就必须遍历整个图;
反之逆邻接表解决了入度却不能解决出度;
那能否将邻接表与逆邻接表结合起来呢?
答案是肯定的,于是就有了一种新的有向图的存储方法:十字链表法。
邻接多重表
边集数组
边集数组是由两个一维数组构成。一个是存储顶点的信息;另一个是存储边的信息,这个边数组每个数据元素有一条边的起点下标(begin)、终点下标(end)和权(weight)组成。
图的遍历:深度优先搜索、广度优先搜素
深度优先搜索:
广度优先遍历:类似于树的层序遍历
深度优先更适合目标比较明确,以找到目标为主的情况,广度优先更适合在不断扩大遍历访问时找到最优解的情况。
最小生成树
定义:给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树,如果边上有权值,那么使得边权和最小的生成树叫做最小生成树。即构成连通网的最小代价生成树称为最小生成树。
实际问题:我们要在n个城市中建立一个通信网络,则连通这n个城市需要布置n-1一条通信线路,这个时候我们需要考虑如何在成本最低的情况下建立这个通信网?
普里姆算法—Prim算法:适合稠密图
【算法思想】:Prime算法是一种贪心算法,它最初将无向连通图G中所有顶点V分成两个顶点集合VA和VB。在计算过程中VA中的点为已经选好连接入生成树的点,否则属于VB。最开始的时候VA只包含任意选取的图G中的一个点u,其余的点属于VB,每次添加一个VB中的点到VA,该点是集合VB到集合VA中距离最小的一个点。直到V个顶点全部属于VA,算法结束。显然出发点不同,最小生成树的形态就不同,但边权和的最小值是唯一的。
eg:
下面我们对下面这幅图求其最小生成树:
假设我们从顶点v1开始,所以我们可以发现(v1,v3)边的权重最小,所以第一个输出的边就是:v1—v3=1:
然后,我们要从v1和v3作为起点的边中寻找权重最小的边,首先了(v1,v3)已经访问过了,所以我们从其他边中寻找,发现(v3,v6)这条边最小,所以输出边就是:v3—-v6=4
然后,我们要从v1、v3、v6这三个点相关联的边中寻找一条权重最小的边,我们可以发现边(v6,v4)权重最小,所以输出边就是:v6—-v4=2.
然后,我们就从v1、v3、v6、v4这四个顶点相关联的边中寻找权重最小的边,发现边(v3,v2)的权重最小,所以输出边:v3—–v2=5
然后,我们就从v1、v3、v6、v4,v2这2五个顶点相关联的边中寻找权重最小的边,发现边(v2,v5)的权重最小,所以输出边:v2—–v5=3
最后,我们发现六个点都已经加入到集合U了,我们的最小生成树建立完成。
【算法步骤】
选定图中的任意一个顶点v0,从v0开始生成最小生成树。
(1)初始化dist[v0]=0,其他点的距离值dist[i]=∞。其中dist[i]表示集合VB中的点到VA中的点的距离值。
(2)经过N次如下步骤操作,最后得到一棵含N个顶点,N-1条边的最小生成树:
①选择一个未标记的点k,并且dist[k]的值是最小的
②标记点k进入集合VA
③以k为中间点,修改未标记点j,即VB中的点到VA的距离值
(3)得到最小生成树T。
克鲁斯卡算法—Kruskal算法:适合稀疏图
【算法思想】:Kruskal算法也是一种贪心算法,它是将边按权值排序,每次从剩下的边集中选择权值最小且两个端点不在同一集合的边加入生成树中,反复操作,直到加入了n-1条边。
【算法步骤】:
(1)将G中的边按权值从小到大快排。
(2)按照权值从小到大依次选边。若当前选取的边加入后使生成树T形成环,则舍弃当前边,否则标记当前边并计数。
(3)重复(2)的操作,直到生成树T中包含n-1条边,否则当遍历完所有边后,选取不到n-1条边,表示最小生成树不存在。
【算法实现】:Kruskal算法
算法的关键在于如何判定新加入的边会不会使图G’产生环,在这里用并查集,如果新加入的边的两个端点在并查集的同一集合中,说明存在环,需要舍弃这条边,否则保留当前边,并合涉及的两个集合。
最短路径
迪杰斯特拉算法(Dijkstra):单源最短路径
【算法思想】:首先将图中的顶点分成两组,第一组S中包括已经确定最短路径的顶点(初始情况包含源点);第二组V-S中包括还未确定最短路径的顶点。然后按照路径长度递增的顺序计算源点到各顶点的最短路径,逐个将第二组中的数据加入到第一组中,直到S = V。
【算法实现】:Dijkstra
【动态演示】
弗洛伊德算法(Floyd):任意两个点对最短路径
【算法思想】:用简单的语言来解释,就是对于点Vi到Vj的距离,如果存在点Vk,使得点Vi到点Vk的距离加上点Vj到点Vk的距离之和小于点Vi到Vj的距离,那么就用点Vi到点Vk的距离加上点Vj到点Vk的距离之和去替代点Vi到Vj的距离。
【算法实现】:Floyd
【结果展示】
8.查找和排序算法
参考链接:
https://blog.csdn.net/Asher117/article/details/89306091
https://blog.csdn.net/Asher117/article/details/89351068
https://blog.csdn.net/Asher117/article/details/93647879
https://mp.weixin.qq.com/s/GjqKMEwLHq16FaXdoHy8xA
https://blog.csdn.net/jiaoyangwm/article/details/80808235
https://blog.csdn.net/dengpei187/article/details/51899550
https://mp.weixin.qq.com/s/Oyk7_vR3KtIBXf5AnhmWNQ
https://blog.csdn.net/qq_39826163/article/details/81660819
https://mp.weixin.qq.com/s/LCs2wmfCGw9oc3d1hkJn2w
https://mp.weixin.qq.com/s/Iul7pHHiAsun80Dad9jqkw
https://blog.csdn.net/qq_38499859/article/details/79122634
https://blog.csdn.net/Asher117/article/details/89500637
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!