图学习笔记索引(全部)
001自定义输入流In类实现
002背包数据类型Bag实现
003无向图数据类型实现
004基于图的深度优先搜索
005使用深度优先搜索找图中的所有连通分量
005-1基于深度优先搜索查找图中连通路径
006基于深度优先搜索判断图中是否存在环
007基于深度优先搜索判断一个无向图图是否是一个二分图
008广度优先搜索查找连通图中的最短路径
009有向图数据类型实现
010有向图的可达性
011带权重的无向边数据类型Edge实现
012加权无向图数据类型实现
从文件中读取无向图图的顶点关系。
tinyWG.txt文件中的第一行为顶点数,第二行为边数。
第三行到最后是两个相邻的顶点:
13
13
0 5
4 3
0 1
9 12
6 4
5 4
0 2
11 12
9 10
0 6
7 8
9 11
5 3
routes.txt 内容:
JFK MCO
ORD DEN
ORD HOU
DFW PHX
JFK ATL
ORD DFW
ORD PHX
ATL HOU
DEN PHX
PHX LAX
JFK ORD
DEN LAS
DFW HOU
ORD ATL
LAS LAX
ATL MCO
HOU MCO
LAS PHX
tinyDG.txt中的内容:
13
22
4 2
2 3
3 2
6 0
0 1
2 0
11 12
12 9
9 10
9 11
8 9
10 12
11 4
4 3
3 5
7 8
8 7
5 4
0 5
6 4
6 9
7 6
tinyEWG.txt中的内容:
8
16
4 5 0.35
4 7 0.37
5 7 0.28
0 7 0.16
1 5 0.32
0 4 0.38
2 3 0.17
1 7 0.19
0 2 0.26
1 2 0.36
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93
package algorithms.graph;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
public class In implements Iterable{
private String infile; //图文件输入
private Integer[] IntegerArr; //使用数组存储单个数字顶点
private String[] stringArr; //使用字符数组存储
private String[] lineArr; //使用数组存储每行顶点
private int index;
private int sindex;
private int line;
public In(String infile) throws IOException{
this.infile = infile;
this.index = 0;
this.sindex = 0;
BufferedReader bf = new BufferedReader(new FileReader(infile));
String textLine;
StringBuffer sb = new StringBuffer();
StringBuffer sbLine = new StringBuffer();
while((textLine=bf.readLine()) != null){
//逐个字符读取
sb.append(textLine.replaceAll(" +", ",") + ","); //去除每行数字中所有空格并以,切分
//sb.append(",");
//逐行读取
sbLine.append(textLine.replaceAll("\\s", " ") + "\n"); //去除每行数字中所有空格并以tab换行
}
//System.out.println(sb.toString());
String[] strVal = sb.toString().split(",");
Integer[] numVal = new Integer[strVal.length];
for (int i = 0; i < strVal.length; i++)
if(!containsDouble(sb.toString()) && !containsString(sb.toString()))
numVal[i] = Integer.parseInt(strVal[i]);
this.IntegerArr = numVal;
String[] strLineVal = sbLine.toString().split("\n"); //逐行存储字符串
this.stringArr = strVal; //顶点字符串的数组存储
this.lineArr = strLineVal;
bf.close();
}
//该方法只针对不含权重的图文件读取;
public Integer[] getArr(){
return this.IntegerArr;
}
//逐个读取数字顶点(该方法只针对不含权重的图文件读取;)
public int readInt(){
if(index < IntegerArr.length && index > -1)
return IntegerArr[index++];
return -1;
}
public boolean hasNextInt(){//当前是否还有可取值
if(index < IntegerArr.length && index > -1)
return true;
return false;
}
public String[] getStr(){
return this.stringArr;
}
//逐个读取字符顶点
public String readStr(){
if(sindex < stringArr.length && sindex > -1)
return stringArr[sindex++];
return null;
}
public boolean hasNextStr(){//当前是否还有可取值
if(sindex < stringArr.length && sindex > -1)
return true;
return false;
}
//返回存储每行顶点的数组
public String[] getLineArr(){
return this.lineArr;
}
public boolean hasNextLine(){
if(line < lineArr.length) return true;
return false;
}
//读取行字符串
public String readLine() {
if(line < lineArr.length)
return lineArr[line++];
return null;
}
//使In类实现迭代器接口
@Override
public Iterator iterator() {
return new Iterator(){
int indexIt = 2; //去除前两个数字,即顶点数和边数
@Override
public boolean hasNext() { //当前是否还有可取值
if(indexIt < IntegerArr.length && indexIt > 1)
return true;
return false;
}
@Override
public Integer next() {
if(indexIt < IntegerArr.length && indexIt > -1)
return IntegerArr[indexIt++];
return -1;
}
};
}
public static boolean containsInteger(String str){
boolean isDigit = false;
//String str = "aaasss8fff";
for(int i = 0 ; i < str.length(); i++){
if(Character.isDigit(str.charAt(i))){
isDigit = true;
break;
}
}
return isDigit;
}
public static boolean containsDouble(String str){
boolean isDouble = false;
//String str = "abc2.0f";
for(int i = 0 ; i < str.length(); i++){
if(str.contains(".")){
isDouble = true;
break;
}
}
return isDouble;
}
public static boolean containsString(String str){
boolean isLetter = false;
//String str = "aaasss8fff";
for(int i = 0 ; i < str.length(); i++){
if(Character.isLetter(str.charAt(i))){
isLetter = true;
break;
}
}
return isLetter;
}
public static void main(String[] args) throws IOException {
System.out.println("测试逐个读取数字:");
In in = new In("D:\\tinyWG.txt");
while(in.hasNextInt())
System.out.println(in.readInt());
System.out.println(in.hasNextInt());
System.out.println("测试逐行读取数字:");
while(in.hasNextLine()){
System.out.println(in.readLine());
}
System.out.println(in.hasNextLine());
System.out.println("测试迭代器:");
In in2 = new In("D:\\tinyWG.txt");
for(int v : in2)
System.out.print(v + " ");
System.out.println();
System.out.println("测试逐行读取字符串顶点:");
String stream = "D:\\routes.txt";
in = new In(stream); //第一遍读取图
while(in.hasNextLine()){
System.out.println(in.readLine());
}
int count = 0;
System.out.println("带权重边的图读取:");
In in3 = new In("D:\\tinyEWG.txt");
for(String v : in3.getStr())
System.out.println(count++ +":"+ v);
System.out.println("带权重边的图读取2:");
In in4 = new In("D:\\tinyEWG.txt");
for(int i = 0; i < 10; i++)
System.out.println(count++ +":"+ in4.readStr());
}
}
输出:
测试逐个读取数字:
13
13
0
5
4
3
0
1
9
12
6
4
5
4
0
2
11
12
9
10
0
6
7
8
9
11
5
3
false
测试逐行读取数字:
13
13
0 5
4 3
0 1
9 12
6 4
5 4
0 2
11 12
9 10
0 6
7 8
9 11
5 3
false
测试迭代器:
0 5 4 3 0 1 9 12 6 4 5 4 0 2 11 12 9 10 0 6 7 8 9 11 5 3
测试逐行读取字符串顶点:
JFK MCO
ORD DEN
ORD HOU
DFW PHX
JFK ATL
ORD DFW
ORD PHX
ATL HOU
DEN PHX
PHX LAX
JFK ORD
DEN LAS
DFW HOU
ORD ATL
LAS LAX
ATL MCO
HOU MCO
LAS PHX
带权重边的图读取:
0:8
1:16
2:4
3:5
4:0.35
5:4
6:7
7:0.37
8:5
9:7
10:0.28
11:0
12:7
13:0.16
14:1
15:5
16:0.32
17:0
18:4
19:0.38
20:2
21:3
22:0.17
23:1
24:7
25:0.19
26:0
27:2
28:0.26
29:1
30:2
31:0.36
32:1
33:3
34:0.29
35:2
36:7
37:0.34
38:6
39:2
40:0.40
41:3
42:6
43:0.52
44:6
45:0
46:0.58
47:6
48:4
49:0.93
带权重边的图读取2:
50:8
51:16
52:4
53:5
54:0.35
55:4
56:7
57:0.37
58:5
59:7