目前这里没有考虑,路径权值与方向
简单的图的深度搜索与广度搜索,备忘
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(); } }