数据结构与算法---图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 图的创建
	/**
	 * 初始化矩阵和VertexList(用来存放顶点的值)
	 * 
	 * @param n表示顶点的个数
	 */
	public Graph(int n) {
		VertexList = new ArrayList<String>(n);
		edges = new int[n][n];
		numOfEdges = 0;
		isVisited = new boolean[n];
	}
//	插入顶点
	public void insertVertex(String vertex) {
		VertexList.add(vertex);
	}

	/**
	 * 添加边 A = 0;B = 1;C = 2;D = 3; E = 4; 假如A与B相连,则v1 = 0,v2 = 1;weight = 1;
	 * 
	 * @param v1     第一个顶点的下标
	 * @param v2     第二个顶点的下标
	 * @param weight 1表示两点相连
	 */
	public void insertEdges(int v1, int v2, int weight) {
		edges[v1][v2] = weight;
		edges[v2][v1] = weight;
		numOfEdges++;
	}

图的常用方法:

//	返回结点的个数
	public int getNumOfVertex() {
		return VertexList.size();
	}

//  返回边的数目
	public int getNumOfEdges() {
		return numOfEdges;
	}

//	返回对应下标的值 0 => A...
	public String getValueByIndex(int index) {
		return VertexList.get(index);
	}

//	返回v1和v2的weight即表示结点之间有无连接的数
	public int getWeight(int v1, int v2) {
		return edges[v1][v2];
	}

//	显示图的方法即矩阵
	public void showGraph() {
		for (int[] link : edges) {
			System.err.println(Arrays.toString(link));
		}
	}
  • 图的深度优先遍历- - -DFS
    在这里插入图片描述
    思想:一条路走到底,“专一”
    深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,首先访问第一个邻接结点,再以这个被访问的邻接结点作为作为初始结点,访问它的第一个邻接结点。直至访问完毕。
    在这里插入图片描述

以此图为例:
在这里插入图片描述
对应的邻接矩阵:
在这里插入图片描述
代码实现:

//	得到第一个邻接结点的下标
	public int getFirstNeighbor(int index) {
		for (int j = 0; j < VertexList.size(); j++) {
			if (edges[index][j] > 0) {
				return j;
			}
		}
		return -1;
	}

//	根据前一个邻接结点的下标来获取下一个邻接结点
	public int getNextNeighbor(int v1, int v2) {
		for (int j = v2 + 1; j < VertexList.size(); j++) {
			if (edges[v1][j] > 0) {
				return j;
			}
		}
		return -1;
	}

//	深度优先遍历算法
//	i 第一次就是0
	public void dfs(boolean[] isVisted, int i) {
//		首先访问该结点
		System.out.print(getValueByIndex(i) + "->");
//		将该结点设置为已访问
		isVisted[i] = true;
//		得到当前结点的下一个存在的结点
		int w = getFirstNeighbor(i);
		while (w != -1) {
//			如果该结点未被访问,则以该结点为起始点进行深度优先搜索
			if (!isVisted[w]) {
				dfs(isVisted, w);
			}
//		如果w结点已经被访问过,继续寻找下一个结点
			w = getNextNeighbor(i, w);
		}
	}

//	对dfs进行重载的方法,遍历所有的结点并进行dfs,解决有非联通图的情况
	public void dfs() {
//		遍历所有的结点进行dfs
		for (int i = 0; i < getNumOfVertex(); i++) {
			if (!isVisited[i]) {
				dfs(isVisited, i);
			}
		}
	}
  • 广度优先遍历—BFS

思想:“广撒网”
从图的某一结点出发,首先依次访问该结点的所有结点,再按这些结点被访问的先后次序依次访问与它们相邻接的所有未被访问的结点。
在这里插入图片描述
代码实现:

	public void bfs(boolean[] isVisted, int i) {
//		表示队列头结点的对应下标
		int u;
//		邻接结点w
		int w;
//		使用队列来记录访问结点的顺序
		LinkedList queue = new LinkedList();
//		首先访问该结点
		System.out.print(getValueByIndex(i)+"->");
//		将该结点设置为已访问
		isVisted[i] = true;
//		将该结点加入队列
		queue.addLast(i);
		while (!queue.isEmpty()) {
//			取出队列的头结点下标
			u = (Integer)queue.removeFirst();
//			得到第一个邻接结点的下标w
			w = getFirstNeighbor(u);
			while (w != -1) {
//				判断是否访问过
				if (!isVisted[w]) {
					System.out.print(getValueByIndex(w)+"->");
					isVisted[w] = true;
					queue.addLast(w);
				}
//				以u为前驱结点,找w后面的下一个结点
				w = getNextNeighbor(u, w);
			}
		}
	}

	public void bfs() {
		for (int i = 0; i < getNumOfVertex(); i++) {
			if (!isVisited[i]) {
				bfs(isVisited, i);
			}
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值