图上的基本分方法可以抽象如下
package lee.graph;
import java.io.FileNotFoundException;
public interface Graph {
public void initGraph(String path) throws FileNotFoundException;
public int getWeight(int v , int w);
public int getFirstNeighbor(int v);
public int getNextNeighbor(int v, int w);
public void setWeight(int v, int w , int power);
public void printGraph();
public int getNumVertex();
public int getNumEdge();
public int getOutDegree(int v);
public int getInDegree(int v);
}
常见的实现有 邻接矩阵法 和邻接表法。 注意图上的算法 和图本书的存储方式是无关的, 很多书都没有严格区分这一点。
图上的算法 比如 最小生成树 最短路径 遍历 拓扑排序等,仅依赖与API而不是图的具体实现。后续的文章会给出图上的常用算法。
邻接矩阵的实现:
package lee.graph;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MatrixGraph implements Graph{
private int numVertex;
private int numEdge;
private int[][] matrix;
public MatrixGraph(int numOfV , int numOfE){
this.numEdge = numOfE;
this.numVertex = numOfV;
matrix = new int[numOfE][numOfE];
}
@Override
public void initGraph(String path) throws FileNotFoundException {
for(int i =0 ; i<numVertex;i++){
for(int j=0;j<numVertex;j++){
matrix[i][j] = 999;
}
}
Scanner in = new Scanner(new FileInputStream(path));
while (in.hasNext()) {
int i = in.nextInt();
int j = in.nextInt();
int weight = in.nextInt();
setWeight(i,j,weight);
}
}
@Override
public int getWeight(int v, int w) {
return matrix[v][w];
}
@Override
public int getFirstNeighbor(int v) {
for(int i=0; i<numVertex;i++){
if(matrix[v][i]!=999 &&v!=i ){
return i;
}
}
return -1;
}
@Override
public int getNextNeighbor(int v, int w) {
for(int i=w+1; i<numVertex;i++){
if(matrix[v][i]!=999 && v!=i){
return i;
}
}
return -1;
}
@Override
public void setWeight(int v, int w, int power) {
matrix[v][w] = power;
}
@Override
public void printGraph() {
for(int i=0; i< numVertex; i++){
for(int j=0; j<numVertex; j++){
if(matrix[i][j] != 999 && i!=j){
System.out.println(i + " " + j + " " + matrix[i][j]);
}
}
}
}
@Override
public int getNumVertex() {
return numVertex;
}
@Override
public int getNumEdge() {
return numEdge;
}
@Override
public int getOutDegree(int v) {
int count=0;
for(int i=0; i<numVertex; i++){
if(matrix[v][i] != 999 && v!=i){
count++;
}
}
return count;
}
@Override
public int getInDegree(int v) {
int count=0;
for(int i=0; i<numVertex; i++){
if(matrix[i][v] != 999 && v!=i){
count++;
}
}
return count;
}
}
注: 节点不连接时,记其权值为999
图的邻接表实现:
package lee.graph;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class LinkedGraph implements Graph{
private int numVertex;
private int numEdge;
ArrNode [] arr;
public LinkedGraph(int numV,int numE){
this.numEdge = numE;
this.numVertex = numV;
arr = new ArrNode[numV];
for(int i=0;i<arr.length;i++){
arr[i] = new ArrNode();
}
}
@Override
public void initGraph(String path) throws FileNotFoundException {
Scanner in = new Scanner(new FileInputStream(path));
while(in.hasNext()){
int i = in.nextInt();
int j = in.nextInt();
int k = in.nextInt();
if(arr[i].next==null){
arr[i].next = new GNode(j,k);
}
else{
GNode p = arr[i].next;
while(p.next!=null){
p=p.next;
}
p.next = new GNode(j,k);
}
}
}
@Override
public int getWeight(int v, int w) {
GNode p = arr[v].next;
while(p!=null && p.num!=w){
p=p.next;
}
if(p==null){
return 999;
}
else{
return p.weight;
}
}
@Override
public int getFirstNeighbor(int v) {
GNode p = arr[v].next;
if(p==null){
return -1;
}
else{
return p.num;
}
}
@Override
public int getNextNeighbor(int v, int w) {
GNode p = arr[v].next;
while(p!=null && p.num!=w){
p=p.next;
}
if(p.num == w && p.next !=null){
return p.next.num;
}
return -1;
}
@Override
public void setWeight(int v, int w, int power) {
GNode p = arr[v].next;
while(p.next!=null && p.num!=w){
p=p.next;
}
if(p.num==w){
p.weight=power;;
}
else{
p.next = new GNode(w,power);
}
}
@Override
public void printGraph() {
for(int i=0;i<numVertex;i++){
GNode p = arr[i].next;
while(p!=null){
System.out.println(i+" "+p.num+" "+p.weight);
p=p.next;
}
}
}
@Override
public int getNumVertex() {
return numVertex;
}
@Override
public int getNumEdge() {
return numEdge;
}
class GNode{
int num;
int weight;
GNode next;
GNode(int n,int w){
this.num = n;
this.weight = w;
}
}
class ArrNode{
GNode next;
}
@Override
public int getOutDegree(int v) {
int count=0;
GNode p = arr[v].next;
while(p!=null){
p=p.next;
count++;
}
return count;
}
@Override
public int getInDegree(int v) {
int count=0;
for(int i =0; i < numVertex; i++){
if(v!=i && getWeight(i,v)!=999){
count++;
}
}
return count;
}
}