您的位置:首页 > 其它

图---邻接矩阵的深度搜索与广度搜索测试一

2013-05-15 13:50 459 查看
目前这里没有考虑,路径权值与方向

简单的图的深度搜索与广度搜索,备忘

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

class Point {
String name;
boolean isVisit;

public Point(String name) {
this.name = name;
}

}

/**
* @author pc
*
*/
public class Graph {
final static int LENGTH = 20;

Point[] points;
int line[][];
int curLength;

public Graph() {
points = new Point[LENGTH];
line = new int[LENGTH][LENGTH];
}

public void addLine(int x, int y) {
line[x][y] = 1;
line[y][x] = 1;
}

public void addPoint(Point v) {
points[curLength++] = v;
}

public void showName(int index) {
System.out.print(points[index].name);
}

public void showNbsp() {
System.out.print(" ");
}

private int getNextPi(Integer x) {
for (int i = 0; i < curLength; i++) {
if (!points[i].isVisit && line[x][i] > 0) {
return i;
}
}
return -1;
}

private void initPoints() {
for (int i = 0; i < curLength; i++) {
points[i].isVisit = false;
}
}

/**
* 深度搜索
* 起始点A,压入堆栈
* 1、A与B存在连线,却 B 未被访问,把B压入堆栈,
* 2、检查B与下一个节点 C 是否存在 ,像条件1的情况,不存在,将B弹出;存在将 C 压入堆栈
* 不存在时:
* 3、检查A与下一个节点关系,重复 1、2、3步,直到堆栈为空。
*/
public void dfs() {
Stack<Integer> stack = new Stack<Integer>();
showName(0);
showNbsp();
stack.push(0);
points[0].isVisit = true;

while (!stack.isEmpty()) {
int i = getNextPi(stack.peek());
if (i < 0) {
stack.pop();
} else {
stack.push(i);
showName(i);
showNbsp();
points[i].isVisit = true;
}
}
initPoints();
}

/**
* 广度搜索
* 起始点A,加入队列
* 1、A与B, C, F 存在连线,却 B, C, F 未被访问,把B, C, F 加入队列,直到没有与A有连接的节点,将A移出队列!
* 2、再从队列头中取出B,循环 条件1的操作。 直到队列为空
*
*/
public void bfs() {
Queue<Integer> queue = new LinkedList<Integer>();
showName(0);
showNbsp();
queue.add(0);
points[0].isVisit = true;
while (!queue.isEmpty()) {
int i = getNextPi(queue.peek());
if (i < 0) {
queue.poll();
} else {
queue.add(i);
showName(i);
showNbsp();
points[i].isVisit = true;
}
}
initPoints();
}

/**
* 最小生成树
*  区别是打印当前节点
*/
public void mfs() {
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
points[0].isVisit = true;

while (!stack.isEmpty()) {
Integer curIndex = stack.peek();

int i = getNextPi(curIndex);
if (i < 0) {
stack.pop();
} else {
stack.push(i);

showName(curIndex);
showName(i);
showNbsp();
points[i].isVisit = true;
}
}
initPoints();
}

/**
* 拓扑排序:
* 不能为一有向环型图
* 找到没有后继节点,加入到序列数据中
*/
public void topo(){
String sortName[] = new String[LENGTH];
int oldCur = curLength;
while(curLength > 0){
int i = noNextPi();
if(i < 0)
throw new RuntimeException("图是一个有向环");
sortName[curLength-1] = points[i].name;

deletePoint(i); //删除 这个节点

}

for(int i = 0; i < oldCur; i++){
System.out.print(sortName[i]);
showNbsp();
}

initPoints();
}

private void deletePoint(int di) {
if(di != curLength - 1){
for(int i = di; i < curLength - 1; i++){
points[i] = points[i+1];
}
for(int row = di; row < curLength - 1; row++){
moveRowUp(row, curLength);
}
for(int col = di; col < curLength - 1; col++){
moveColLeft(col, curLength);
}
}
curLength--;
}

private void moveColLeft(int col, int length) {
for (int j = 0; j < length; j++) {
line[j][col] = line[j][col + 1];
}
}

private void moveRowUp(int row, int length) {
for (int j = 0; j < length; j++) {
line[row][j] = line[row + 1][j];
}
}

private int noNextPi() {
// 找出没有子节点的
for (int i = 0; i < curLength; i++) {
boolean hasNext = false;
for (int j = 0; j < curLength; j++) {
if (line[i][j] > 0) {
hasNext = true;
}
}

if (!hasNext) {
return i;
}
}

return -1;
}

public static void printLn(String name){
System.out.println("");
System.out.println(name);
}
public static void main(String[] args) {
Graph g = new Graph();
for (int i = 65; i <= 70; i++) {
char c = (char) i;
Point point = new Point(c + "");
g.addPoint(point);
}

g.addLine(0, 1); // ab
g.addLine(0, 2); // ac
g.addLine(0, 5); // af

g.addLine(1, 3); // bd

g.addLine(2, 3); // cd
g.addLine(2, 4); // ce

g.addLine(3, 4); // de

printLn("深度搜索:");
g.dfs();

printLn("广度搜索:");
g.bfs();

printLn("最小生成树:");
g.mfs();

//printLn("拓扑排序:");
//g.topo();

}

}






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: