一、基础
算法公式:
①
∑Ni=0Ai=AN+1−1A−1
②
∑Ni=1ik=Nkk+1
(k!=-1)
定义:
① 如果存在正常数c和
n0
使得当N>=
n0
时T(N)<=cf(N),则记为T(N)=O(f(N))。
② 如果存在正常数c和
n0
使得当N>=
n0
时T(N)>=cg(N),则记为T(N)=
Ω(g(N))
。
③ T(N) =
Θ(h(N))
当且仅当 T(N) = O(h(N)) 和 T(N)=
Ω(h(N))
④ 如果对每一正常数c 都存在常数
n0
使得当N>
n0
时T(N)< cp(N),则T(N)=o(p(N)).有时也可以说,如果T(N)=O(p(N))且T(N)!=
Θ(p(N))
,则T(N)=o(p(N)).
二分查找最坏查找次数:
log2N+1
欧几里得算法,M N最大公因数,和N M%N最大公因数相同。
后缀表达式(逆波兰)
中缀表达式:a+b*c+(d * e+f) * g 转换为 后缀表达式: abc * +de * f+g * +
算法:
(–算法实现–)
尾递归:递归调用在最后一行,可以转换为while循环
二、树
二叉树是TreeSet和TreeMap的实现基础。
树的实现:
class TreeNode{
Object element;
TreeNode firstChikd;
TreeNode nextSibling;
}
先序遍历:对节点的处理工作是在它的诸儿子节点被处理之前进行的。
后序遍历,中序遍历
层序遍历:对所有深度为d的节点要在深度d+1的节点之前进行处理。层序遍历与其他类型的遍历不同的地方在于它不是递归的执行的;它用到队列,而不使用递归所默认的栈。
二叉树:每个节点都不能多于两个儿子。平均深度
O(N−−√)
实现:
class BinaryNode{
Object element;
BinaryNode left;
BinaryNode right;
}
二叉查找树:在二叉树中,对于树中每个节点X,它的的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。
(–关于二叉查找树 增删查(查询最大节点最小节点)–)
懒惰删除:对树进行删除,如果删除次数不多,通常使用。当一个元素要被删除时,它仍留在树中,而只是被标记为删除。这特别在有重复项时很常用,因为此时记录出现频率数的域可以减1.如果树中的实际点数和“被删除”的节点数相同,那么树的深度预计只上升一个小的常数,因此,存在一个与懒惰删除相关的非常小的时间损耗。再有,如果被删除的项是重新插入的,那么分配一个新的单元的开销就避免了。
AVL树,带有平衡条件的二叉查找树。其每个节点的左子树和右子树的高度最多差1的二叉查找树(空树的高度为-1)。
旋转:当插入节点向AVL树中,会破坏其平衡性,采用旋转维持平衡性。单旋转,双旋转。
单旋转:解决外边子树过高。双旋转:解决内部。
(–旋转算法–)
伸展树 插入操作进行随机插入,不进行平衡的维持,当访问一个节点时,该节点就要经过一系列AVL树的旋转被推倒根上。注意,如果一个节点很深,那么其路径上就存在许多的也相对较深的节点,通过重新构造可以减少对所有这些节点的进一步访问所花费的时间。而且在许多应用中,当一个节点被访问时,它很可能不久再被访问。每次访问,对节点进行展开操作
展开:令访问的节点成为根节点,而他的左右子树深度
在减小。
(–展开算法–)
B树
为了对磁盘尽量少的访问(磁盘每次访问会读取 一块,块大小一般为1024B),将树的同一个节点的儿子节点数设置块的大小,加快读取。即:M叉树
阶为M的B树是具有下列特性的树:
1.数据存储在树叶上
2.非叶节点存储直到M-1个关键字以指示搜索方向;关键字i代表子树i+1中的最小的关键字。(非树叶节点最多有M-1个关键字)
3.树的根或者是一片树叶,或者其儿子数在2和M之间
4.除根外,所有非树叶节点的儿子数在
⌈M/2⌉
和M之间
5.所有的树叶都在相同的深度上并有
⌈L/2⌉
和L之间个数据。
每个节点代表一个磁盘区块,我们根据所存储的项的大小选择M和L
B树、B-树、B+树、B*树 参考http://www.cnblogs.com/oldhorse/archive/2009/11/16/1604009.html
红黑树:TreeSet和TreeMap实现原理
经验指出红黑树大约和平均AVL树一样深,从而查找时间一般接近最优。红黑树的优点是执行插入所需要的开销相对较低,另外就是实践中发生的旋转相对较少。
http://www.cnblogs.com/v-July-v/archive/2010/12/29/1983707.html
三、散列
散列函数:空间一般素数大小
再散列:
解决冲突:1.分离链接法:使用链表
2.线性探测法:后面的位置一个一个的试,看是否占用
3.平方探测法: 1 ,2 ,4位置实验
4.双散列:冲突,常识位置:2*hash(x) 3*hash(x)……
四、优先队列(堆)
优先队列:至少允许下列两种操作:insert,deleteMin
二叉堆:1.结构性:堆是一颗被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。这样的树成为完全二叉树。其高度:O(logN),可以用数组表示
2.堆序性质:对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字
insert(插入):上虑操作,将新元素插入到最后的位置,不断与父元素比较,移动到相应的位置。最坏运行时间O(logN),平均运行时间为常数(业已证明,执行一次插入平均需要2.607次比较,平均上移操作元素1.607层)
deleteMin(删除最小):将根元素置为空,最后的元素移到根位置,不断与子元素比较,移动位置
buildHeap(构建堆):对一个数组元素进行构建堆,花费时间O(N),(从数组中间值进行下虑,只要进行一半数据的下虑操作)
堆元素插入删除:时间复杂度:O(logN)
d堆:儿子节点有d个
左式堆:加深左路劲,右路径更短。支持O(logN)合并操作
斜堆:递归进行合并,O(logN),不需要满足左式堆
左式堆和斜堆都在每次操作以O(logN)时间有效的支持合并、插入、和deleteMin。二叉堆以每次操作花费常数平均时间支持插入。二项队列支持所有这三种操作,每次操作的最坏情形运行时间为O(logN),而插入操作平均花费常数时间。
二项队列:http://blog.csdn.net/changyuanchn/article/details/14648463
五、排序
http://blog.csdn.net/hguisu/article/details/7776068
六、不相交集
http://blog.csdn.net/changyuanchn/article/details/16810535
七、图论
Dijkstra算法:最短路径贪婪算法
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
最小生成树:
一个无向图G的最小生成树就是由该图的那些链接G的所有顶点的边构成的树,且其总价值最低
Prim算法:
Kruskal算法:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html