算法: 红黑树、分治算法和图的遍历

红黑树

性质

(1)   每个结点是红色或者是黑色;

(2)   根结点是黑色;

(3)   每个叶结点,即空结点(NIL)是黑色的;

(4)   如果一个结点是红色,那么它的两个子结点都是黑色;(隐含条件:红色节点的父节点也是黑色)

对每个结点,从该结点到其所有后代叶结点的所有路径上包含相同数目的黑结点。

性质4和5共同决定了:最长路径的节点总数量不会超过最短路径的两倍。因为黑色节点数量要一样,红色不能连着来,从而路径全黑时最短,红黑交替时最长

红黑树插入操作

步骤 1: 查找要插入的位置;

步骤 2: 将新结点的颜色域赋值为红色;

步骤 3: 自下而上重新调整该树为红黑树;


分治算法

分治法所能解决的问题一般具有以下几个特征:

该问题的规模缩小到一定的程度就可以容易地解决;

该问题可以分解为若干个规模较小的同类型问题

利用该问题分解出的子问题的解可以合并为该问题的解;

该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

在用分治法设计算法时,最好使子问题的规模大致相同。即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想

为了降低时间复杂度,必须减少乘法的次数。

实例

(1)大整数乘法;

(2)Strassen矩阵乘法;

若依此定义来计算A和B的乘积矩阵C,则每计算C的一个元素C[i][j],需要做n次乘法和n-1次加法。因此,算出矩阵C的 个元素所需的计算时间为O(n3)

使用与上例类似的技术,将矩阵A,B和C中每一矩阵都分块成4个大小相等的子矩阵。由此可将方程C=AB重写

(3)棋盘覆盖;

在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖

(4)最接近点对问题;

(5)循环赛日程表。


图的遍历

图的概念

图是由顶点集合(vertex)及顶点间的关系集合组成的一种数据结构:Graph=( V, E )

其中    V = { x | x 属于 某个数据对象}

是顶点的有穷非空集合;

E = {(x, y) | x, y Î V }

是顶点之间关系的有穷集合,也叫做边(edge)集合。

有向图中,顶点对 <x, y> 是有序的。在无向图中,顶点对(x, y)是无序的。

完全图   

若有 n 个顶点的无向图有 n(n-1)/2 条边, 则此图为完全无向图。

有 n 个顶点的有向图有n(n-1) 条边, 则此图为完全有向图。

邻接顶点   

如果 (u, v) 是 E(G) 中的一条边,则称 u 与 v 互为邻接顶点。

  某些图的边具有与它相关的数, 称之为权。这种带权图叫做网络

顶点的度  一个顶点v的度是与它相关联的边的条数。记作TD(v)。在有向图中, 顶点的度等于该顶点的入度与出度之和。

路径    在图 G=(V, E) 中, 若从顶点 vi 出发, 沿一些边经过一些顶点 vp1, vp2, …, vpm,到达顶点vj。则称顶点序列 (vi  vp1 vp2 ... vpm  vj) 为从顶点vi 到顶点 vj 的路径。它经过的边(vi, vp1)、(vp1, vp2)、...、(vpm, vj) 应是属于E的边。

路径长度  非带权图的路径长度是指此路径上边的条数。带权图的路径长度是指路径上各边的权之和。

简单路径   若路径上各顶点 v1, v2, ..., vm 均不互相重复, 则称这样的路径为简单路径。

连通图与连通分量   在无向图中, 若从顶点v1到顶点v2有路径, 则称顶点v1与v2是连通的。如果图中任意一对顶点都是连通的, 则称此图是连通图。非连通图的极大连通子图叫做连通分量。

强连通图与强连通分量    在有向图中, 若对于每一对顶点vi和vj, 都存在一条从vi到vj和从vj到vi的路径, 则称此图是强连通图。非强连通图的极大强连通子图叫做强连通分量。

生成树   一个连通图的生成树是其极小连通子图,在 n 个顶点的情形下,有 n-1 条边。

邻接表是邻接矩阵的改进形式。为此需要把邻接矩阵的各行分别组织为一个单链表。

已给的连通图中某一顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历

DFS深度

DFS 在访问图中某一起始顶点 v 后,  由 v 出发, 访问它的任一邻接顶点 w1; 再从 w1 出发, 访问与 w1邻 接但还没有访问过的顶点 w2;  然后再从 w2 出发, 进行类似的访问, … 如此进行下去,  直至到达所有的邻接顶点都被访问过的顶点 u 为止。

BFS广度

BFS在访问了起始顶点 v 之后, 由 v 出发, 依次访问 v 的各个未被访问过的邻接顶点 w1, w2, …, wt, 然后再顺序访问 w1, w2, …, wt 的所有还未被访问过的邻接顶点。再从这些访问过的顶点出发,再访问它们的所有还未被访问过的邻接顶点,… 如此做下去,直到图中所有顶点都被访问到为止。

广度优先搜索是一种分层的搜索过程, 每向前走一步可能访问一批顶点, 不像深度优先搜索那样有往回退的情况。因此, 广度优先搜索不是一个递归的过程。

构造最小生成树的准则

必须使用且仅使用该网络中的 n-1 条边来联结网络中的 n 个顶点;

不能使用产生回路的边;

各边上的权值的总和达到最小

克鲁斯卡尔算法的基本思想:最小堆和并查集来实现克鲁斯卡尔算法。

设有一个有 n 个顶点的连通网络 N = { V, E }, 最初先构造一个只有 n 个顶点, 没有边的非连通图 T = { V, Æ },  图中每个顶点自成一个连通分量。当在 E 中选到一条具有最小权值的边时, 若该边的两个顶点落在不同的连通分量上,则将此边加入到 T 中; 否则将此边舍去,重新选择一条权值最小的边。如此重复下去, 直到所有顶点在同一个连通分量上为止。

普里姆算法的基本思想:

从连通网络 N = {V, E}中的某一顶点 u0 出发, 选择与它关联的具有最小权值的边 (u0, v), 将其顶点加入到生成树顶点集合U 中。

以后每一步从一个顶点在集合U 中,  而另一个顶点不在集合U 中的各条边中选择权值最小的边(u, v), 把它的顶点加入到集合U 中。如此继续下去, 直到网络中的所有顶点都加入到生成树顶点集合U 中为止。

最短路径问题:

如果从图中某一顶点(称为源点)到另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小

边上权值非负情形的单源最短路径问题

               —  Dijkstra算法

 边上权值为任意值的单源最短路径问题

                — Bellman和Ford算法

所有顶点之间的最短路径

                — Floyd算法

Dijkstra算法可描述如下:

① 初始化: S¬{v0};  

         dist[j]¬Edge[0][j],   j = 1, 2, …, n-1;

                                         // n为图中顶点个数

② 求出最短路径的长度:

         dist[k]¬min {dist[i]},  iÎV-S ;

         S¬S∪{k};

③ 修改:  

         dist[i]¬min{dist[i], dist[k]+Edge[k][i]},

               对于每一个 iÎV-S ;

④ 判断:若 S = V, 则算法结束,否则转②。

有向图中的强连通片

找出强连通片可以看成是对图中每个结点染成相应的颜色,考虑基于DFS来解决

难点在于,不同的强连通片之间虽然没有环,但是仍然有可能连通

遍历时,有可能从一个强连通片跨入到另一个强连通片

思路:

1. 有向图的压缩图是一个有向无环图,根据拓扑排序的分析,压缩图中必然存在一个出度为0的点,同时也必然存在拓扑排序

2. 每个节点在完成处理时,进入一个节点栈。按照先结束访问,先入栈的顺序

3. 将图G转置得到GT,然后从节点栈中依次取出节点进行第二轮遍历

广度优先遍历的应用

判断二分图

对于无向图G =(V, E ),如果存在顶点V的划分V1、V2,使得图中任意的边均满足它的一个顶点在V1 , 另一个顶点在V2 ,那么G就被称为二分图。

一个图是二分图等价于它是可以二着色的,即可以将任意一个顶点染为红色或者蓝色,并且使得任意一条边的两个顶点的颜色不同。

思路:

1. 从任意一个节点v开始,对图G进行二着色

2. 将节点v染为蓝色

3. 对于v的每一个邻居w:如果w没有被染色,则将其染为黄色;如果w已经被染色,且颜色为蓝色,则可知图G不是二分图

4. 对每个邻居w,循环执行步骤2

5. 遍历每个节点后,如果没有发现着色矛盾的情况,可知图G是二分图

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值