定义:
图是由一组顶点和一组能够将两个顶点相连的边组成的
相关术语:
- 当两个顶点通过一条边相连时,我们称这两个顶点是相邻的,并称这条边依附于这两个顶点
- 某个顶点的度数即为依附于它的边的总数。
- 子图是由一幅图的所有边的一个子集(以及它们所依附的所有的顶点)组成的图。
在图中,
路径
是由边顺序连接的一系列顶点。
简单路径
是一条没有重复顶点的路径。
环
是一条至少含有一条边且起点和终点相同的路径。
简单环
是一条(除了起点和终点必须相同之外)不含有重复顶点和边的环。路径或者环的长度为其中所包含的边数。
思路(类似走迷宫):
1、选择一条没有标记过的通道,在你走过的路上铺一条绳子
2、标记所有你第一次路过的路口和通道
3、如果来到的路口被标记过了,就回退到上个路口
4、回退的路口已没有可走的通道时继续回退
相关数据类型
package algorithm.graph;
import java.util.Iterator;
/**
* 描述:
* Created by zjw on 2021/7/25 12:29
*/
public class Bag<Item> implements Iterable<Item> {
private Node first;//持有空引用
private class Node{
Item item;
Node next;
}
public void add(Item item){
Node oldNode = new Node();
first.item = item;
first.next = oldNode; //在头部添加节点
}
@Override
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator<Item> implements Iterator<Item>{
//保留指向链表的节点的引用first
private Node curNode = first;
@Override
public boolean hasNext() {
return curNode != null;
}
@Override
public Item next() {
Item item = (Item) curNode.item;
curNode = curNode.next;
return item;
}
}
public static void main(String[] args) {
Bag<Integer> bag = new Bag<Integer>();
for(int i = 0; i < 10; i++)
bag.add(i);
for(Integer i : bag)
System.out.print(i+" ");
}
}
--------------------------------------
public class In implements Iterable<Integer>{
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<Integer> iterator() {
return new Iterator<Integer>(){
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;
}
深度优先搜索
定义
1、递归遍历所有顶点
2、将它标记为已访问
3、递归地访问它的所有没有被标记过的邻居顶点
package algorithm.graph;
/**
* 描述:深度优先搜索
*
* Created by zjw on 2021/7/25 12:38
*/
public class DepthFirstSearch {
private boolean[] marked;
private int count;
public DepthFirstSearch(Graph G, int s) {
marked = new boolean[G.V()];
dfs(G, s);
}
private void dfs(Graph G, int v) {
marked[v] = true;
count++;
for (Integer w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
}
}
public boolean marked(int w) {
return marked[w];
}
public int count() {
return count;
}
}
标签:优先,return,String,int,private,算法,搜索,顶点,public
From: https://blog.51cto.com/u_11906056/7067574