图的相关算法(1)
补充–连接表的图的代码
若不了解图请看前文:
背包
背包是一种不支持从中删除元素的的数据结构,它的目的是负责收集元素,并且能够迭代遍历所有收集到的元素,背包中不保存存储数据时候的顺序;
随后实现连接表的图的结构时会利用到这个背包的数据结构
public class Bag<T> implements Iterable{
private T[] array;
private int bagSize;
private static final int DEFAULT_CAPACITY = 10;
public Bag() {
ensureCapacity(DEFAULT_CAPACITY);
}
public Bag(int size) {
if (size>DEFAULT_CAPACITY)
ensureCapacity(size);
else
ensureCapacity(DEFAULT_CAPACITY);
}
public void add(T t){
if (array.length == bagSize)
ensureCapacity(array.length<<1);
array[bagSize++]=t;
}
private void ensureCapacity(int capactity){
T[] newArray = (T[])new Object[capactity];
for (int i = 0; i < array.length; i++) {
newArray[i]=array[i];
}
array = newArray;
}
@Override
public Iterator<T> iterator() {
return new ArrayIterator();
}
private class ArrayIterator implements Iterator<T>{
int currentPosition;
@Override
public boolean hasNext() {
return currentPosition<bagSize;
}
@Override
public T next() {
if (!hasNext()) throw new NoSuchElementException();
return array[currentPosition++];
}
}
}
邻接表–表示图
public class Graph {
private final int V;//顶点数码
private int E;//边的数目
private Bag<Integer>[] adj;
public Graph(int V) {
this.V = V;
this.E = 0;
adj = (Bag<Integer>[]) new Bag[V];
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
}
public int V() {
return V;
}
public int E() {
return E;
}
public void addEdge(int v, int w) {
adj[v].add(w);
adj[w].add(v);
E++;
}
public Iterable adj(int v) {
return adj[v];
}
}
使用深度优先搜索查找图中的路径
public class DepthFirstPath {
private boolean[] marked;//
private int[] edgeTo;//从起点到一个顶点的已知路径的最后一个顶点
private final int s;//起点
public DepthFirstPath(Graph G ,int s) {
marked = new boolean[G.V()];
edgeTo = new int[G.E()];
this.s = s;
dfs(G,s);
}
private void dfs(Graph G, int v) {
marked[v]=true;
Bag<Integer> adj = G.adj(v);
for (int w : G.adj(v)) {
edgeTo[w] = v;
dfs(G,w);
}
}
public boolean hasPathTo(int v){
return marked[v];
}
public Iterable<Integer> pathTo(int v){
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<>();
for (int x= v ; x!=s;x = edgeTo[x]){
path.push(x);
}
path.push(s);
return path;
}
}
使用广度优先搜索查找广度图中的路径
public class BreadthFirstSearch {
private boolean[] marked;
private int[] edgeTo;
private final int s;
public BreadthFirstSearch(Graph G, int s) {
this.s = s;
marked = new boolean[G.V()];
edgeTo = new int[G.E()];
bfs(G, s);
}
private void bfs(Graph G, int v) {
Queue<Integer> queue = new Queue<>();
marked[v] = true;
queue.enqueue(v);
while (!queue.isEmpty()){
int s = queue.dequeue();
for (int w : G.adj(s)) {
if (!marked[w]){
queue.enqueue(w);
edgeTo[s] = w;
marked[w] = true;
}
}
}
}
// hasPathTo 和 pathTo 方法同dfs中;
}