图的概念

图的概念

1.什么是图

图是一种和树相像的数据结构,通常有一个固定的形状,这是有物理或抽象的问题来决定的。

1.      邻接

如果两个顶点被同一条边连接,就成这两个顶点为邻接的。

2.      路径

路径是从一个顶点到另一个顶点经过的边的序列。

3.      连通图和非连通图

至少有一条路径可以连接所有的顶点,那么这个图就是连通的,否则是非连通的。

4.      有向图和无向图

有向图的边是有方向的,如只能从A到B,不能从B到A

无向图的边是没有方向的,可以从A到B,也可以从B到A

5.      带权图

在有些图中,边被赋予了一个权值,权值是一个数字,它可以代表两个顶点的物理距离,或者是一个顶点到另一个顶点的时间等。这样的图叫做带权图。

6.      用程序来实现图

代码实现:

/**
 * 顶点类
 * @author Administrator
 *
 */
public class Vertex {
	private char label;
	
	public Vertex(char label) {
		this.label = label;
	}
}
/**
 * 图
 * @author Administrator
 *
 */
public class Graph {
	//顶点数组
	private Vertex[] vertexList;
	//邻接矩阵
	private int[][] adjMat;
	//顶点的最大数目
	private int maxSize;
	//当前顶点
	private int nVertex;
	
	public Graph() {
		vertexList = new Vertex[maxSize];
		adjMat = new int[maxSize][maxSize];
		for(int i = 0; i < maxSize; i++) {
			for(int j = 0; j < maxSize; j++) {
				adjMat[i][j] = 0;
			}
		}
		nVertex = 0;
	}
	
	/**
	 * 添加顶点
	 */
	public void addVertex(char label) {
		vertexList[nVertex++] = new Vertex(label);
	}
	
	/**
	 * 添加边
	 */
	public void addEdge(int start,int end) {
		adjMat[start][end] = 1;
		adjMat[end][start] = 1;
	}
	
}
public class TestGraph {
	public static void main(String[] args) {
		Graph g = new Graph();
		g.addVertex('A');
		g.addVertex('B');
		g.addVertex('C');
		
		g.addEdge(0, 1);
		g.addEdge(0, 2);
		g.addEdge(1, 2);
	}
}


图的搜索

1.图的搜索

图的搜索是指从一个指定的顶点可以到达哪些顶点。

1.      搜索的分类:

                        i.             深度优先搜索DFS

                      ii.             广度优先搜索BFS

2.      深度优先搜索规则:

a)        如果可能,访问一个邻接的未访问过的顶点,标记它,并把它放入栈中。

b)        如不能执行规则1时,如果栈不能空,就从栈中弹出一个顶点。

c)        当不能执行规则1和规则2时,就完成了整个搜索过程。

3.      深度优先搜索代码实现

4.      广度优先搜索规则:

a)        访问下一个邻接的未访问过的顶点,这个顶点必须是当前节点的邻接点,标记它,并把它插入到队列中。

b)        如果无法执行规则1,那么就从队列头取出一个顶点,并使其作为当前顶点。

c)        当队列为空不能执行规则2时,就完成了整个搜索过程。

代码实现

/**
 * 顶点类
 * @author Administrator
 *
 */
public class Vertex {
	public char label;
	public boolean wasVisited;
	
	public Vertex(char label) {
		this.label = label;
	}
}
public class MyStack {
	//底层实现是一个数组
	private long[] arr;
	private int top;
	
	/**
	 * 默认的构造方法
	 */
	public MyStack() {
		arr = new long[10];
		top = -1;
	}
	
	/**
	 * 带参数构造方法,参数为数组初始化大小
	 */
	public MyStack(int maxsize) {
		arr = new long[maxsize];
		top = -1;
	}
	
	/**
	 * 添加数据
	 */
	public void push(int value) {
		arr[++top] = value;
	}
	
	/**
	 * 移除数据
	 */
	public long pop() {
		return arr[top--];
	}
	
	/**
	 * 查看数据
	 */
	public long peek() {
		return arr[top];
	}
	
	/**
	 * 判断是否为空
	 */
	public boolean isEmpty() {
		return top == -1;
	}
	
	/**
	 * 判断是否满了
	 */
	public boolean isFull() {
		return top == arr.length - 1;
	}
}
import ch03.MyStack;

/**
 * 图
 * @author Administrator
 *
 */
public class Graph {
	//顶点数组
	private Vertex[] vertexList;
	//邻接矩阵
	private int[][] adjMat;
	//顶点的最大数目
	private int maxSize = 20;
	//当前顶点
	private int nVertex;
	//栈
	private MyStack stack;
	
	public Graph() {
		vertexList = new Vertex[maxSize];
		adjMat = new int[maxSize][maxSize];
		for(int i = 0; i < maxSize; i++) {
			for(int j = 0; j < maxSize; j++) {
				adjMat[i][j] = 0;
			}
		}
		nVertex = 0;
		stack = new MyStack();
	}
	
	/**
	 * 添加顶点
	 */
	public void addVertex(char label) {
		vertexList[nVertex++] = new Vertex(label);
	}
	
	/**
	 * 添加边
	 */
	public void addEdge(int start,int end) {
		adjMat[start][end] = 1;
		adjMat[end][start] = 1;
	}
	
	public int getadjUnvisitedVertex(int v) {
		for(int i = 0; i < nVertex; i++) {
			if(adjMat[v][i] == 1 && vertexList[i].wasVisited == false) {
				return i;
			}
		}
		return -1;
	}
	
	public void dfs() {
		//首先访问0号顶点
		vertexList[0].wasVisited = true;
		//显示该顶点
		displayVertex(0);
		//压入栈中
		stack.push(0);
		while(!stack.isEmpty()) {
			//获得一个未访问过的邻接点
			int v = getadjUnvisitedVertex((int)stack.peek());
			if(v == -1) {
				//弹出一个顶点
				stack.pop();
			} else {
				vertexList[v].wasVisited = true;
				displayVertex(v);
				stack.push(v);
			}
		}
		
		//搜索完以后,要将访问信息修改
		for(int i = 0; i < nVertex; i++) {
			vertexList[i].wasVisited = false;
		}
		
	}
	
	public void displayVertex(int v) {
		System.out.print(vertexList[v].label);
	}
	
}
public class TestGraph {
	public static void main(String[] args) {
		Graph g = new Graph();
		g.addVertex('A');
		g.addVertex('B');
		g.addVertex('C');
		g.addVertex('D');
		g.addVertex('E');
		
		g.addEdge(0, 1);
		g.addEdge(1, 2);
		g.addEdge(0, 3);
		g.addEdge(3, 4);
		
		g.dfs();
	}
}

运行结果:

ABCDE

图的最小生成树

1. 最小生成树

连接每个顶点最少的连线。最小生成树边的数量总是比顶点的数量少1.

代码实现:

/**
 * 顶点类
 * @author Administrator
 *
 */
public class Vertex {
	public char label;
	public boolean wasVisited;
	
	public Vertex(char label) {
		this.label = label;
	}
}
public class MyStack {
	//底层实现是一个数组
	private long[] arr;
	private int top;
	
	/**
	 * 默认的构造方法
	 */
	public MyStack() {
		arr = new long[10];
		top = -1;
	}
	
	/**
	 * 带参数构造方法,参数为数组初始化大小
	 */
	public MyStack(int maxsize) {
		arr = new long[maxsize];
		top = -1;
	}
	
	/**
	 * 添加数据
	 */
	public void push(int value) {
		arr[++top] = value;
	}
	
	/**
	 * 移除数据
	 */
	public long pop() {
		return arr[top--];
	}
	
	/**
	 * 查看数据
	 */
	public long peek() {
		return arr[top];
	}
	
	/**
	 * 判断是否为空
	 */
	public boolean isEmpty() {
		return top == -1;
	}
	
	/**
	 * 判断是否满了
	 */
	public boolean isFull() {
		return top == arr.length - 1;
	}
}
import ch03.MyStack;

/**
 * 图
 * @author Administrator
 *
 */
public class Graph {
	//顶点数组
	private Vertex[] vertexList;
	//邻接矩阵
	private int[][] adjMat;
	//顶点的最大数目
	private int maxSize = 20;
	//当前顶点
	private int nVertex;
	//栈
	private MyStack stack;
	
	public Graph() {
		vertexList = new Vertex[maxSize];
		adjMat = new int[maxSize][maxSize];
		for(int i = 0; i < maxSize; i++) {
			for(int j = 0; j < maxSize; j++) {
				adjMat[i][j] = 0;
			}
		}
		nVertex = 0;
		stack = new MyStack();
	}
	
	/**
	 * 添加顶点
	 */
	public void addVertex(char label) {
		vertexList[nVertex++] = new Vertex(label);
	}
	
	/**
	 * 添加边
	 */
	public void addEdge(int start,int end) {
		adjMat[start][end] = 1;
		adjMat[end][start] = 1;
	}
	
	public int getadjUnvisitedVertex(int v) {
		for(int i = 0; i < nVertex; i++) {
			if(adjMat[v][i] == 1 && vertexList[i].wasVisited == false) {
				return i;
			}
		}
		return -1;
	}
	
	public void dfs() {
		//首先访问0号顶点
		vertexList[0].wasVisited = true;
		//显示该顶点
		displayVertex(0);
		//压入栈中
		stack.push(0);
		while(!stack.isEmpty()) {
			//获得一个未访问过的邻接点
			int v = getadjUnvisitedVertex((int)stack.peek());
			if(v == -1) {
				//弹出一个顶点
				stack.pop();
			} else {
				vertexList[v].wasVisited = true;
				displayVertex(v);
				stack.push(v);
			}
		}
		
		//搜索完以后,要将访问信息修改
		for(int i = 0; i < nVertex; i++) {
			vertexList[i].wasVisited = false;
		}
		
	}
	
	public void displayVertex(int v) {
		System.out.print(vertexList[v].label);
	}
	
	public void mst() {
		//首先访问0号顶点
		vertexList[0].wasVisited = true;
		//压入栈中
		stack.push(0);
		while(!stack.isEmpty()) {
			//当前顶点
			int currentVertex = (int)stack.peek();
			//获得一个未访问过的邻接点
			int v = getadjUnvisitedVertex(currentVertex);
			if(v == -1) {
				//弹出一个顶点
				stack.pop();
			} else {
				vertexList[v].wasVisited = true;
				
				stack.push(v);
				displayVertex(currentVertex);
				System.out.print("-");
				displayVertex(v);
				System.out.print(" ");
			}
		}
		
		//搜索完以后,要将访问信息修改
		for(int i = 0; i < nVertex; i++) {
			vertexList[i].wasVisited = false;
		}
	}
	
}
public class TestGraph {
	public static void main(String[] args) {
		Graph g = new Graph();
		g.addVertex('A');
		g.addVertex('B');
		g.addVertex('C');
		g.addVertex('D');
		g.addVertex('E');
		
		g.addEdge(0, 1);
		g.addEdge(0, 2);
		g.addEdge(0, 3);
		g.addEdge(0, 4);
		g.addEdge(1, 2);
		g.addEdge(1, 3);
		g.addEdge(1, 4);
		g.addEdge(2, 3);
		g.addEdge(2, 4);
		g.addEdge(3, 4);
		
		g.mst();
	}
}
运行结果:

A-B B-C C-D D-E 











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值