算法设计与分析课程Part1笔记(5)

5.1 迪杰斯特拉算法

        迪杰斯特拉用来解决单源最短路径问题,该问题的输入是给定的有向图G,边的长度是非负的,给定源节点s;输出是节点s到G中其他节点的最短路径长度。

很自然想到利用之前的BFS进行最短路径的计算,但是只有当长度为1的时候,才有效。有一种想法就是将图G中边程度大于1的边进行分解,分解为多条长度为1的边,如果一条边够长,那么这种做法十分麻烦。

Dijkstra算法(s):

-- x=[s](x是一个节点的集合)

-- A[s]=0

-- B[s]=emptypath

-- while x≠V

  -- among all edges (v,w)∈E,with v∈x,w∈V-x, pickone that minimize A[v]+low(the edge(v1,w1))

  -- add w1 to x

  -- set A[w1]=A[v]+low

  -- set B[v1]=B[v1]+edge(v1,w1)

         Dijkstra算法的时间复杂度是O(mn).

         如果图G中有的边长为负,迪杰斯特拉算法有失效的情况,既然为负,可以考虑大家都加上一个正常数,然后用该算法,但是也不能保证其正确性。

5.2 堆

         数据结构可以十分有效的组织数据从而便于高效的处理,例如列表、堆栈、堆、队列、树等。

         不同的数据机构用于不同的场景。数据结构掌握的层级分为:0level—明白什么是数据结构;1level—能使用简单的已有数据结构;2level—能时候高级数据结构;3level—能根据实际需求编写相应数据结构。

         堆数据结构是一种数组对象,可以视为一颗完全二叉树,堆有最大堆和最小堆之分。最大堆,即根元素比左右子树上的元素都大,最小堆则是都小。

堆的几个基本操作有:

       插入元素(O(logn)); 提出最大值或最小值(O(logn),删除根然后调整)

       建立堆(n);删除元素(O(logn))

      如果对中第i个元素发生变动(例如被删除),递归检查左右元素,则堆进行调整的复杂度为O(logn);建立堆的过程是对非叶子节点进行调整的过程。

堆的应用:

1.排序。通过建立堆,每次抽取最大或最小元素,然后进行调整。(O(nlogn))

2.保持中值。快速的从x1,x2…xi中个元素中找出中值元素,可以利用最大堆或最小堆,然后通过i/2次删除
3.用于加速迪杰斯特拉算法,可以达到O(mlogn)

5.3 哈希表

        哈希表用来保存一个集合(可以是动态变化的)。

        支持的操作有:Insert、Delete、Lookup,这三个操作都是O(1).

        哈希表的应用:1.删除一组元素中的重复元素;2.2-SUM问题,即对于一个n个元素的数组A和给定的一个和t,求出A中任意元素x和y使得x+y等于t的组合。对于第二个问题,如果野蛮的进行遍历,需要O(n2),如果先排序,然后用二叉树进行搜索,则复杂度为O(nlogn),而用哈希表则只需要O(n)即建立哈希表所需时间和遍历A所需时间;3.编译器中符号表的实现;4.搜索算法的。

        对于给定的一个空间U,里面有很多元素,我们需要保存其中的一部分S(其中S≤U),如果用一个包括U个元素的数组表示,未免就太浪费空间了,利用一个哈希函数将U中的元素映射到一个有限空间进行存储,这就是哈希表的思想。通常把哈希表中的一个元素叫做一个桶(bucket)。

        映射的时候,常常碰到的问题就是碰撞问题,就是对不同的key,哈希函数计算值却相同,解决的方法主要是链式哈希表和开放地址法。其中链式哈希表中的桶是一个链表,其中包括了哈希值都为某个值的元素列表;开放地址法中,每个桶值保存一个元素。

        碰撞问题十分常见,具有随机生日的n个人,要使得随机选择的两个人生日相同,则n至少为23即可,可见,碰撞问题十分频繁。

你可能感兴趣的:(数据结构,算法,delete,存储,insert,编译器)