哈希,最短路径,堆,排序,动态规划

一 最短路径

最短路径分为单源最短路径和任意两点的最短路径,前者用Dijkstra算法,后者用floyed算法。

Dijkstra算法是一种广度优先算法,以起始点层层往外扩展,直至到终点为止。其把顶点分为两个集合:

  1. 已经求出最短路径的节点集合 S

  2. 未确定最短路径的顶点集合U

通过逐渐把U中的节点不端加入到S中,直至U为空。再插入的过程中,要保证V到S中的任意顶点长度不大于V到U中任意顶点长度

 假设在中间某一步的时候,上一步选取t节点作为中间节点,那么此时查看t的out vertex,那么查看V经过t到这些out vertex的边的长度的最小值是否比之前不经过t的小,如果小,则进行更新。

floyed算法:

i -> j 的最短路径无外乎两种可能:

  1. i 直接到 j

  2. i 经过若干中间节点到 j ,即Dis(i,k) + Dis(k,j)   和   Dis(i,j) 的大小比较~~

二. 哈希

Hash主要为了在O(1)时间复杂度下查找一个元素。Hash函数的定义:一般是取原始字符的某几位(或随机)映射为一个hash值,比如可以取前几位,把原始字符串分成不同的段,段之间相加得到映射后的hash值。

Hash中两个比较重要的点是:

  1. 映射后的hash值分布要均匀

  2. 映射后的hash值得冲突要尽量少

一般冲突发生后,可以解决的方法:

  1. 线性探测法:在附近依次找一个hash值为空的位置,一定能找到一个,但是增加冲突的可能,因为hash后的值会更聚集。

  2. 二次探测法:不长不是加1,步长1 2 4 8 ... 增加

  3. 伪随机

  以上三种方法属于开放定址法。还有两种方法分别是 再hash方法,链地址法。

三. 检索

  检索看的是查找成功/不成功的时候的平均查找长度ASL。不同于检索排序看中的则是元素的比较次数和元素的移动次数

  1. 顺序查找

  2. 分块查找:块间有序,块内无序,块内顺序查找。

  动态查找/静态查找。

   二叉搜索树,ASL容易受树的形态影响。因此对树的形态加个限制,变成了平衡二叉搜索树,其左右子树深度之差不超过2,只能是1,-1,0. 

  AVL中比较重要的操作就是左旋,右旋操作,调整树,使得树变成平衡的树。

  旋转的情况分为下面四种情况:

    当前节点的左子树插入左节点:右旋

    当前节点的左子树插入右节点:左旋

    当前节点的右子树插入左节点:右旋

    当前节点的右子树插入右节点:左旋

四. 排序

  1. 找出数组中超过一半的数字

     维持两个数字,一个是目前出现次数比较多的数字,一个是该数字出现的次数count,遍历数组,如果当前数字和保存的数字相同,则count + 1,如果不相同,则count - 1。如果count = 0,则保存数字 = 当前的数字,重新计数,count + 1

   2. 堆建成后,如何进行堆排序呢?每次将堆顶得元素和堆的最后一次元素替换,并将最后一个原色从堆中删除,重新调整堆,依次这样可以得到一个有序的序列。堆排序不受初始数字的排列顺序影响,时间复杂度恒为O(nlogn)

   3. 插入排序:把后面未排序数组第一个数字依次插入到前面已排序数组中。时间复杂度O(nn),受初始数字序列的影响

      二分插入排序:插入排序的一种小改进,时间复杂度O(nn)

      希尔排序:根据一个递减序列 d1 d2 ... 1,d1为增量元素把原始数组划分成不同的组,对组内元素进行排序。时间复杂度O(nlogn)

      选择排序:从后面未排序数组中选择一个最大/小值插入到已排序数组中去

      冒泡排序:依次交换两个数字,使得大的在后,小的在前,每次都能把最大的一个元素沉淀到数组最后面

      快速排序:

      堆排序:

      归并排序:讲数组分成元素个数只有1/2个的小数组,依次向上进行归并。

      桶排序:将数据划分到不同的桶内,桶之间是有序的,对桶内的元素排序即可。

      基数排序:将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零. 然后, 从最低位开始, 依次进行一次稳定排序(我们常用上一篇blog介绍的计数排序算法, 因为每个位可能的取值范围是固定的从0到9).这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.

比如这样一个数列排序: 342 58 576 356, 以下描述演示了具体的排序过程(红色字体表示正在排序的数位)

第一次排序(个位):

3 4 2

5 7 6

3 5 6

0 5 8

第二次排序(十位):

3 4 2

3 5 6

0 5 8

5 7 6

第三次排序(百位):

0 5 8

3 4 2

3 5 6

5 7 6

结果: 58 342 356 576

两个问题:

  • 为什么要从低位开始向高位排序?

        如果要从高位排序, 那么次高位的排序会影响高位已经排好的大小关系. 在数学中, 数位越高,数位值对数的大小的影响就越大.从低位开始排序,就是对这种影响的排序. 数位按照影响力从低到高的顺序排序, 数位影响力相同则比较数位值.

  • 为什么同一数位的排序子程序要使用稳定排序?

        稳定排序的意思是指, 待排序相同元素之间的相对前后关系,在各次排序中不会改变.比如实例中具有十位数字5的两个数字58和356, 在十位排序之前356在58之前,在十位排序之后, 356依然在58之前.

        稳定排序能保证,上一次的排序成果被保留,十位数的排序过程能保留个位数的排序成果,百位数的排序过程能保留十位数的排序成果.

 

索引查找:由索引表和数据表组成。索引表可以是线性的,也可以是树状结构的。

posted on 2015-06-04 10:56  keketse  阅读(685)  评论(0编辑  收藏  举报

导航