[转】二叉树与图的深度优先和广度优先遍历.
(2011-07-20 02:49:35) 标签: 杂谈 |
图的深度优先搜查法是树的先根遍历的普及,它的大约信念是:从图G的某个顶峰v0动身,拜会v0,然后抉择一个与v0邻接且没被拜会过的顶峰vi访 问,再从vi动身抉择一个与vi邻接且未被拜会的顶峰vj举行拜会,顺次继续。万一目前被拜会过的顶峰的所有邻接顶峰都已被拜会,则退回到已被拜会的顶峰 序列中最后一个具有未被拜会的邻接顶峰的顶峰w,从w动身按同样的措施前进遍历,直到图中所有顶峰都被拜会。
图的广度优先搜查是树的按层次遍历的普及,它的大约信念是:率先拜会初始点vi,并将其符号为已拜会过,随后拜会vi的所有未被拜会过的邻接点 vi1,vi2, …, vi t,并均符号已拜会过,然后再按照vi1,vi2, …, vi t的次序,拜会每一个顶峰的所有未被拜会过的邻接点,并均符号为已拜会过,顺次类推,直到图中所有和初始点vi有路径相通的顶峰都被拜会过为止。
二叉树的深度优先遍历的非递归的通用做法是批准栈,广度优先遍历的非递归的通用做法是批准队列。
深度优先遍历分为三种:前序,中序,后序。
率先我们懂得,前序遍历的法定是:
根结点→左子结点→右子结点
中序遍历是:左子结点→根结点→右子结点
后序遍历是:左子结点→右子结点→根结点
已知某二叉树的前序是abdgcefh,中序dgbaechf,则后序是?
那么,对于一棵二叉树,前序遍历的第一个结点定然是这棵树的根结点,即根结点是a。
在中序遍历的次序dgbaechf中,以a分成左、右两旁,左边是dgb,右边是echf。
因而,这棵树目前能够确定如下:
a
/ /
dgb echf
接下来再离别对左子树和右子树举行相仿的垄断。
对于左子树dgb来说,在前序遍历abdgcefh中找到bdg,验证这子树的根是b,那么目前能够确定的树构造如下:
a
/ /
b echf
/
dg
再看dg,前序遍历中的次序为dg,因而d是dg这局部子树的根,那么又因为中序遍历的dg次序也是dg,因而g是右子结点。
即:
a
/ /
b echf
/
d
/
g
目前看echf这局部子树,前序中次序是cefh,因而子树根结点是c,那么左子结点是e,右子树是hf:
获得:
a
/ /
b c
/ / /
d e hf
/
g
最后只剩下hf局部了,前序遍历中是fh,因而根是f,那么h即便左子结点。
目前获得了整棵树:
a
/ /
b c
/ / /
d e f
/ /
g h
对这棵树再举行后序遍历就行了,收获即便:DGEBHFCA
A
B C
D E F
G H
二叉树的排序的阅读措施:
http://om/songQQ/archive/2009/10/20/1587126.html
图的广度优先遍历
图的广度优先遍历BFS算法是一个分层搜查的过程,和树的层序遍历算法类同,它也必需一个队列以坚持遍历过的顶峰次序,以便按出队的次序再去拜会这些顶峰的邻接顶峰。
1.连贯图的广度优先遍历算法信念。
(1)顶峰v入队列。
(2)当队列非空时则继续厉行,否则算法告终。
(3)出队列获得队头顶峰v;拜会顶峰v并符号顶峰v已被拜会。
(4)查找顶峰v的第一个邻接顶峰col。
(5)若v的邻接顶峰col未被拜会过的,则col入队列。
(6)继续查找顶峰v的另一个新的邻接顶峰col,转到环节(5)。直到顶峰v的所有未被拜会过的邻接点处理完。转到环节(2)。
【例】下面以图( a )为例解释广度优先搜查的过程。率先从起点 v 1 动身拜会 v 1 。 v 1 有两个未曾拜会的邻接点 v 2 和 v 3 。先拜会 v 2 ,再拜会 v 3 。然后再先拜会 v 2 的未曾拜会过的邻接点 v 4 、 v 5 及 v 3 的未曾拜会过的邻接 v 6 和 v 7 ,最后拜会 v 4 的未曾拜会过的邻接点 v 8 。至此图中所有顶峰均已被拜会过。获得的顶峰拜会序列为:
2.广度优先遍历算法
(1)邻接矩阵的广度优先遍历算法:
【算法7.1】
void AdjMWGraph::Depth(int v,邦妮兔int visited[])
{ sqQueue< int>q; //定义队列queue
q.EnQueue(v); //顶峰v入队列
while(!q.IsEmpty()) //当队列非空时循环
{ v=q.DeQueue(); //出队列获得队头顶峰u
cout<<endl<<"顶峰"<<v+1<<"权值:"<<Vertices[col]; //拜会顶峰v
visited[col]=1;//符号顶峰v已拜会
for(int col=0;col<numV;col++)
if(Edge[v][col]>0;&&Edge[v][col]<MaxWeight&&visite[col]==0)
q.EnQueue(col);
}
cout<<endl<<"end!"<<"endl;
};
邻接矩阵表示图时,搜查一个顶峰的所有邻接点需花费O(n)工夫,则从n个顶峰动身搜查的工夫应为O(n2),即BFS算法的工夫混杂度是(n2)。
(2)邻接链表的深度优先遍历算法:
【算法7.2】
void AdjTWGraph::BroadFirst(int v, int visited[])
{ int vj; Edge *p; SqQueue <int> Q; Q.EnQueue(v);
while(!Q.IsEmpty()) //队列不空,循环
{ v=Q.DeQueue(); //出队并且拜会顶峰v
cout<<Vertices[v].data<<" "; visited[v]=1;
p=Vertices[v].adj; //取v的邻接边结点
while(p!=NULL) { vj=p->dest; //取v的邻接点编号vj
if(visited[vj]==0) Q.EnQueue(vj); //vj未拜会,入队
p=p->next; //取下一个邻接边结点
}
}
}
利用邻接链表来表示图时,其 BFS 算法的工夫混杂度为 O(n+e) ,这里 e 为无向图中边的数目或有向图中弧的数目。import java.awt.Dimension; /***Example class.The x and y
-
不对阿好像
g都是d的右节点了 后序遍历d怎么在g前面呢? 应该是gdbehfca吧