算法
1线构--------------------------------------------------------------
数组 连快
单向链表 慢 -+高 ArrayList/Vector
双向链表 前/后驱点
栈顶stack L_IN F_OUT 栈Peek=>push/pop Collection.stack
队列Queue F_IN F_OUT L+F-
2树构--------------------------------------------------------------
二叉 根/父/子 双亲/孩子/兄弟
结点度=>子树数目
叶子度=>零
分支结点度>0
树度=>树中结点的最大的度
层次:根结点=1,其余结点=结点的双亲结点+1
无序/有序=>树中结点的各子树之间的次序不重要,可以交换位置
森林:0、多个不相交的树
二叉 <=2子树 [空,根空,左右子空]
第i层 结点数<=2~{i-1} (i≥1)
深度k 结点数<=2~{k}-1(k≥1)
n个结点树高>=log2 (n+1)
任二叉树,若终点个数n0,度为2的结点数n2,则n0=n2+1
满二叉<==>高度h且2~{h} –1个结点
完全二叉<==>叶子:最下层(树左部)、次下层
最下2层度<2
满二叉=>完全二叉
查找:左key[y] <= key[x]<= key[z]右
左子树_结点值<根_结点值<右子树_结点值 键值不相等
parent-->key left-->key-->right
遍历:前序(根-->左子树-->右子树)
中序(左子树-->根-->右子树)
后序(左子树-->右子树-->根)
前驱:该节点左子树中最大节点
后继:该节点右子树中最小节点
AVL 高平衡二叉,任何节点的两个子树的高度<=1。
伸展 查找时间小,被查频率高条目经常处于靠近树根的位置
每次查找后对树重构,查找条目搬移到离树根近地方,自调整形式,
从某个节点到树根之间的路径,系列的旋转这个节点搬移到树根
哈夫曼树
n个权值作为n个叶子结点,若树的带权路径长度达到最小
路径:从一个结点往下可以达到的孩子或孙子结点之间的通路
路径长度:规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1
[WPL]所有叶子结点的带权路径长度之和
如:5,6,7,8,15=》 5,6=》11,7,8,15 5,6=》11,7,8=》15,15
5,6=》11,7,8=》15,11,15=》26,15
3堆--------------------------------------------------------------
二叉堆
完全二元树或者是近似完全二元树,按数据排列方式:最大堆和最小堆。
最大堆:父结点的键值总是大于或等于任何一个子节点的键值;
最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
当向最大堆中添加数据时:先数据加入到最大堆最后
然后尽可能把这个元素往上挪,直到挪不动为止
当从最大堆中删除数据时:先删除该数据,然后最大堆中最后一个元素插入这个空位;
接着,把这个“空位”尽量往上挪,直到剩余的数据变成一个最大堆
4图--------------------------------------------------------------
无向图
点(vertex)点的连线(edge),点"顶点(vertex)"点与点连线"边或弧"(edege)
记G=(V,E)
(01)V1={A,B,C,D,E,F}。 V1表示由"A,B,C,D,E,F"顶点组集合。
(02)E1={(A,B),(A,C),(B,C),(B,E),(B,F),(C,F), (C,D),(E,F),(C,E)}
E1是由边(A,B),边(A,C)...等等组成的集合。其中,(A,C)表示由顶点A和顶点C连接成的边。
有向图
(01) V2={A,C,B,F,D,E,G}。 V2表示由"A,B,C,D,E,F,G"顶点组集合。
(02) A2={<A,B>,<B,C>,<B,F>,<B,E>,<C,E>,<E,D>,<D,C>,<E,B>,<F,G>}
E1是由矢量<A,B>,矢量<B,C>...等等组成的集合。其中,矢量<A,B)表示由"顶点A"指向"顶点C"的有向边
邻接点 一条边上两个顶点
如:上面无向图G0中的顶点A和顶点C就是邻接点。
有向图中顶点的入边,以该顶点为终点的边
顶点的出边,以该顶点为起点的边。
如:面有向图G2中的B和E是邻接点;<B,E>是B的出边,还是E的入边
无向图中某个顶点度是邻接到该顶点的边(或弧)数目。
如,上面无向图G0中顶点A的度是2
有向图中,"入度"和"出度"之分。
顶点的入度,以该顶点为终点的边数目
顶点的出度,以该顶点为起点的边数目。
顶点的度=入度+出度。
如,上面有向图G2中,顶点B的入度是2,出度是3;顶点B的度=2+3=5
路径:顶点(Vm)到顶点(Vn)之间存在一个顶点序列。则表示Vm到Vn是一条路径
路径长度:路径中"边的数量"
简单路径:一条路径上顶点不重复出现
回路:路径的第一个顶点和最后一个顶点相同
简单回路:第一个顶点和最后一个顶点相同,其它各顶点都不重复的回路
连通图(无向图): 任意两个顶点之间都存在一条无向路径
强连通图(有向图): 任意两个顶点之间都存在一条有向路径
5存储结构----------------------------------------
邻接矩阵:
A[i][j]=1 Vi->Vj有边 /0 Vi->Vj无边
无向图:一维数组用来保存顶点信息
有向图:二维数组来用保存边的信息
缺点:比较耗费空间。
邻接表:
缺点是不方便判断两点之间是否有边,更省空间
深度优先搜索:无向图 顶点ABCDEFG按顺序存储
搜索先A,A邻接点=>若多个邻接点则ABCDEFG按顺序优先访问(已访问节点略计)
若无邻接点则返回前一节点进行邻接点访问(已访问节点略计)
有向图 顶点ABCDEFG按顺序存储
搜索先A,A出边=>若多个出边顶点则ABCDEFG按顺序优先访问(已访问出边顶点略计)
若无出边顶点则返回前一顶点进行出边顶点访问(已访问出边顶点略计)
广度/宽度/横向优先搜索:
[[以v为起点,先路径长度1层.......n层,每层按ABCDEFG按顺序]]
顶点v出发,v之后依次访问v的各个未曾访问过的邻接点,
然后从这些邻接点出发依次访问它们的邻接点
[先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问
直至图中所有已被访问的顶点的邻接点都被访问到
如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点
重复上述直至图中所有顶点都被访问到为止
无向图 以v为起点,由近至远,依次访问与v有路径相通且路径长度为1,2...的顶点
有向图 以v为起点出边,由近至远,依次访问与v有路径相通且路径长度为1,2...的顶点
6排序----------------------------------------
冒泡
简单、稳定 1趟复度O(N),N-1趟复度O(N~2)
若干次遍历要排序数列
每次遍历,从前往后依次的比较相邻两个数大小,如前者>后者则交换位置。
1次遍历后最大元素在数列末尾
相同方法再遍历后第二大元素被排列最大元素之前
重复此操作,直到整个数列都有序为止
快速(Quick Sort)
分治法 不稳 O(N2),均复度O(N*lgN)
(1) 从数列中挑出一个基准值。
(2) 将所有<基准值的摆放在基准前面
所有>基准值的摆在基准的后面(相同的数可以到任一边)
这个分区退出之后,该基准就处于数列的中间位置。
(3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序
直接插入(Straight Insertion Sort)
1趟复度O(N),N-1趟=>O(N~2) 稳
[n]个待排元素:1有序、1无序表
开始=>有序表:1元素;无序表:n-1个元素
排序=>每次从无序表取出第1元素,插入到有序表中适当位置,使为新有序表
重复n-1次排序
希尔(Shell Sort)
直接插入改进 不稳
复杂度与步长gap有关 gap=1成直接插入复杂度O(N²),Hibbard增量复杂度O(N3/2)
n个待排序数列
gap<n的整数gap(gap步长):待排序元素分成若干个组子序列
(1)所有距离gap倍数的记录放同一个组
(2)各组内元素进行直接插入排序
(3)1趟排序后,每1组元素有序
(4)减小gap,并重复执行上述的分组和排序
重复操作,gap=1时整数列有序的
选择(Selection sort)
简单直观
1趟复度O(N),N-1趟==>复杂度O(N~2) 稳
先在未排数列中找到最小(or最大)元素放到数列的起始
再从剩余未排元素继续找最小(or最大)元素,放到已排序列末尾
以此类推,直到所有元素均排序完
堆 ① 初始堆:数列a[1...n]构成最大堆,a[1]最大值
② 交换数据:a[1]和a[n]交换,使a[n]是a[1...n]中的最大值;
然后将a[1...n-1]重新调整为最大堆
后将a[1]和a[n-1]交换,使a[n-1]是a[1...n-1]中的最大值;
然后将a[1...n-2]重新调整为最大值
依次类推,直整个数列有序
最大堆排如下:
a[1...n]最大堆排 a[1]:最大值MAX1<==>已排组{a[MAX1]}
未排组{a[1...n-1];a[1]=a[n];}
a[1...n-1]最大堆排 a[1]:最大值MAX2<==>已排组{a[MAX1,MAX2]}
未排组{a[1...n-2];a[1]=a[n-1];}
a[1...n-2]最大堆排 a[1]:最大值MAX3<==>已排组{a[MAX1,MAX2,MAX3]}
未排组{a[1...n-3];a[1]=a[n-2];}
...................................
归并
1趟复杂度O(N),趟数(二叉深度)复杂度是O(N*lgN) 稳
下往上归并 待排序数列分成长度1子列,
将数列两两合并;得长度2有序列
再将数列两两合并;得长度4有序列
再将数两两合并;
直合并1个数列
上往下归并=>下往上反方向
① 分解 -- 当前区间1分为2,分裂点 mid = (low + high)/2;
② 求解 -- 递归地对2子区间a[low...mid] 和 a[mid+1...high]归并排序=>递归终结条件 子区间长度1。
③ 合并 -- 将已排序2个子区间a[low...mid]和 a[mid+1...high]归并1有序区间a[low...high]
桶排(Bucket Sort)
数组分有限量的桶里
待排序组a[N],范围(0, MAX)
桶组r[MAX],元素为0为1个桶
排序,遍历a[N],a[i]值=桶组r下标
如:数组a[3]=5,r[5]=1
基数Radix Sort 桶排扩展
整数按位数切割,每位数比较
待排数 同长度数位,数位较短前面补零
从最低位开始,依次进行1次排
从最低位排~最高位排
成有序列
1. 同长数位不足前0
2. 个位数桶排
3. 十位数桶排
4. 百位数桶排
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步