关于图的深度优先的递归和非递归算法
2016-04-21 18:53
288 查看
题目:给定一个无向图,给出它的深度遍历
先给出图
从S出发,按照字母顺序深度遍历图可得出的结果:SABCDEFGH
这个图十分的特殊,可以检测到有些错误的遍历方法,有些错误的遍历方法有时候可以通过简单的图,但是这张图是不行的,至于如何证明,笔者这里不多加证明
下面给出我的代码:
import java.util.Stack;public class bianli {
private Object[] jiedian;//存储节点
private int num;//节点个数
private int juzhen[][];//邻接矩阵
private boolean visit[];//判断是否遍历
// 初始化
public bianli(int n) {
num = n;
juzhen = new int
;
jiedian = new Object
;
visit = new boolean
;
for (int i = 0; i < n; i++) {
visit[i] = false;
for (int j = 0; j < n; j++) {
juzhen[i][j] = 0;
}
}
}
//初始化节点
public void addjiedian(Object ob[]) {
this.jiedian = ob;
}
//初始化边
public void addbian(int i, int j) {
if (i == j)
return;
else {
juzhen[i][j] = 1;
juzhen[j][i] = 1;
}
}
//遍历边
public void visit(int n) {
visit
= true;
System.out.print(jiedian
);
}
//第一个邻接点
public int firstAdjcent(int i) {
for (int j = 0; j < num; j++) {
if (juzhen[i][j] > 0 && visit[j] == false) {
return j;
}
}
return -1;
}
// i 节点后其余的邻接点
public int nextAdjcent(int i, int k) {
for (int j = k + 1; j < num; j++) {
if (juzhen[i][j] > 0 && visit[j] == false) {
return j;
}
}
return -1;
}
// 递归深度遍历
public void deptravel() {
System.out.println("递归深度遍历:");
for (int j = 0; j < num; j++) {
if (!visit[j]) {
this.travel(j);
}
}
}
public void travel(int i) {
if (visit[i] == false) {
this.visit(i);//如果没有遍历就遍历
for (int j = this.firstAdjcent(i); j >= 0; j = this.nextAdjcent(i,
j)) {
if (!visit[j]) {
this.travel(j);//找到i的邻接点然后递归遍历
}
}
}
}
// 非递归遍历
public void dptravel() {
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < num; i++) {
visit[i] = false;
}
System.out.println("非递归遍历");
for (int i = 0; i < num; i++) {
if (!visit[i]) {
stack.push(i);
while (!stack.isEmpty()) {
int j = (Integer) stack.pop();
if (!visit[j]) {
this.visit(j);//将母节点遍历,然后将它的子节点按照字母逆序入栈,这样可以在栈顶访问它的最近邻接点,继续将它的邻接点入栈,每次其实都是访问的它的最近邻接点,这样出栈的顺序就是访问的顺序
for (int k = num - 1; k > 0; k--) {
if (juzhen[j][k] > 0 && visit[k] == false) {
stack.push(k);
}
}
}
}
}
}
}
public static void main(String[] args) {
bianli test = new bianli(9);
Character jiandian[] = { 'S', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
test.addjiedian(jiandian);
test.addbian(0, 1);
test.addbian(0, 5);
test.addbian(1, 2);
test.addbian(1, 4);
test.addbian(2, 3);
test.addbian(3, 8);
test.addbian(3, 4);
test.addbian(4, 7);
test.addbian(4, 5);
test.addbian(5, 6);
test.addbian(6, 7);
test.addbian(7, 8);
test.deptravel();
System.out.println();
test.dptravel();
}
}
相关文章推荐
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- php中使用key,value,current,next和prev函数遍历数组的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#使用foreach遍历哈希表(hashtable)的方法
- php递归遍历多维数组的方法
- C#使用yield关键字让自定义集合实现foreach遍历的方法
- C#常见的几种集合 ArrayList,Hashtable,List<T>,Dictionary<K,V> 遍历方法对比