【alg4-圖】有向圖
阿新 • • 發佈:2020-12-21
有向圖
在有向圖中,邊是單向的:每條邊所連線的兩個頂點都是一個有序對,它們的鄰接性是單向的。
術語
定義:一幅有方向性的圖是由一組頂點和一組有方向的邊組成的,每條有方向的邊都連線著有序的一對頂點。
出度:一個頂點的出度為由該頂點指出的邊的總數。
入度:一個頂點的入度為指向該頂點的邊的總數。
頭:一條有向邊的第一個頂點稱為它的頭。
尾:第二個頂點稱為它的尾。
除了特殊的圖,一幅有向圖中的兩個頂點的關係可能有4種:
- 沒有邊相連;
- 存在從v到w的邊v->w;
- 存在從w到v的邊w->v;
- 即存在v->w也存在w->v,即雙向的連線。
有向路徑:由一系列頂點組成,對於其中的每個頂點都存在一條有向邊從它指向序列中的下一個頂點。
簡單有向環:是一條不含有重複的頂點和邊的環。
長度:路徑或環的長度即為其中所包含的邊數。
API
API | 功能 |
---|---|
Digraph(int V) | 建立一幅含有V個頂點但沒有邊的有向圖 |
Digraph(int V, int E, int[][] data) | 讀取一幅有向圖 |
int V() | 頂點總數 |
int E() | 邊的總數 |
void addEdge(int v, int w) | 向有向圖中新增一條邊v->w |
Iterable<Integer> adj(int v) | 由v指出的邊所連線的所有頂點 |
Digraph reverse() | 該圖的反向圖 |
String toString() | 物件的字串表示 |
鄰接表表示有向圖
輸入:
表示:
程式碼
Bag.java
package section1_3;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Bag<Item> implements Iterable<Item> {
private Node<Item> first;
private int n;
private class Node<Item> {
Item item;
Node<Item> next;
}
public Bag() {
first = null;
n = 0;
}
public boolean isEmpty() {
return first == null;
}
public int size() {
return n;
}
public void add(Item item) {
Node oldfirst = first;
first = new Node<>();
first.item = item;
first.next = oldfirst;
n++;
}
@Override
public Iterator<Item> iterator() {
return new LinkedIterator(first);
}
private class LinkedIterator implements Iterator<Item> {
private Node<Item> current;
public LinkedIterator(Node<Item> first) {
current = first;
}
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
}
Digraph.java
package section4_2;
import section1_3.Bag;
public class Digraph {
public final int V;
private int E;
private Bag<Integer>[] adj;
public Digraph(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<>();
}
}
public Digraph(int V, int E, int[][] data) {
this(V);
int e = E;
for (int i = 0;i < e;i++) {
int v = data[i][0];
int w = data[i][1];
addEdge(v,w);
}
}
public int V() {
return V;
}
public int E() {
return E;
}
public void addEdge(int v, int w) {
adj[v].add(w);
E++;
}
public Iterable<Integer> adj(int v) {
return adj[v];
}
public Digraph reverse() {
Digraph R = new Digraph(V);
for (int v = 0;v < V;v++) {
for (int w : adj(v)) {
R.addEdge(w,v);
}
}
return R;
}
public String toString() {
String s = V + " vertices, " + E + " edges\n";
for (int v = 0;v < V;v++) {
s += v + ": ";
for (int w : this.adj(v)) {
s += w + " ";
}
s += "\n";
}
return s;
}
}