重新整理數據結構與算法(c#)—— 圖的深度遍歷和廣度遍歷[十一]

前言

簡介圖:

在數據的邏輯結構D=(KR)中,如果K中結點對於關係R的前趨和後繼的個數不加限制,即僅含一種任意的關係,則稱這種數據結構爲圖形結構。

來源百度百科

圖形結構是一種比樹形結構更復雜的非線性結構。在樹形結構中,結點間具有分支層次關係,每一層上的結點只能和上一層中的至多一個結點相關,但可能和下一層的多個結點相關。而在圖形結構中,任意兩個結點之間都可能相關,即結點之間的鄰接關係可以是任意的

然後就是盜圖階段:

後面就是一些基礎常識,我找到一個比較全的:

https://www.cnblogs.com/songgj/p/9107797.html

正文

那麼就來看一下圖的深度遍歷和廣度遍歷吧。

先來定義一個圖:

public class Graph
{
	private List<String> vertexList; //存儲頂點集合
	private int[,] edges; //存儲圖對應的鄰結矩陣
	private Boolean[] isVisited;// 判斷是否訪問了
	int numOfEdges;
	public Graph(int n){
		vertexList = new List<string>();
		edges = new int[8, 8];
		isVisited = new Boolean[8];
	}
	/// <summary>
	/// 增加節點
	/// </summary>
	/// <param name="vertex">節點</param>
	public void addVertex(string vertex)
	{
		vertexList.Add(vertex);
	}
	public void insertEdge(int x,int y,int weight)
	{
		//增加他們的連線 且設置他們的權重
		edges[x, y] = 1;
		edges[y, x] = 1;
		numOfEdges++;
	}

	public void showEdges()
	{
		for (int i=0;i< isVisited.Length;i++)
		{
			for (int j = 0; j < isVisited.Length; j++)
			{
				Console.Write(edges[i,j]+"  ");
			}
			Console.WriteLine();
		}
	}
}

測試一下:

String[] Vertexs = { "1", "2", "3", "4", "5", "6", "7", "8" };
//創建圖對象
Graph graph = new Graph(Vertexs.Count());
//循環的添加頂點
foreach (String vertex in Vertexs)
{
	graph.addVertex(vertex);
}
//更新邊的關係
graph.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
graph.insertEdge(3, 7, 1);
graph.insertEdge(4, 7, 1);
graph.insertEdge(2, 5, 1);
graph.insertEdge(2, 6, 1);
graph.insertEdge(5, 6, 1);
graph.showEdges();
Console.ReadKey();

結果:

這麼看可能不清晰哈,那麼我畫個圖,看一下。

這是下面這張圖哈:

深度遍歷:

private int getFirstNeighbor(int index)
{
	for (int j = 0; j < isVisited.Length; j++)
	{
		if (edges[index, j] > 0)
		{
			return j;
		}
	}
	return -1;
}
/// <summary>
/// 通過鄰接節點來獲取下一個節點
/// </summary>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
public int getNextNeighbor(int v1, int v2)
{
	for (int j = v2+1; j < isVisited.Length; j++)
	{
		if (edges[v1, j] > 0)
		{
			return j;
		}
	}
	return -1;
}
/// <summary>
/// 深度遍歷
/// </summary>
/// <param name="i"></param>
public void dfs(int i)
{
	//打印遍歷的值
	Console.Write(vertexList[i]+"  ");
	isVisited[i] = true;
	int w = getFirstNeighbor(i);
	while (w != -1)
	{
		if (!isVisited[w])
		{
			dfs(w);
		}
		w = getNextNeighbor(i,w);
	}
}

然後調用函數:

 graph.dfs(0);

得到的結果是:

看下廣度遍歷吧:

//對一個結點進行廣度優先遍歷的方法
public void bfs(int i)
{
	//打印遍歷的值
	Console.Write(vertexList[i] + "  ");
	LinkedList<int> queue = new LinkedList<int>();
	queue.AddLast(i);
	int u;
	while (queue.Count != 0)
	{
		u = queue.First.Value;
		queue.RemoveFirst();
		int w = getFirstNeighbor(i);
		while (w != -1)
		{
			if (!isVisited[w])
			{
				Console.Write(vertexList[w] + "  ");
				isVisited[w] = true;
				queue.AddLast(w);
			}
			w = getNextNeighbor(u, w);
		}
	}
}

然後調用:

Console.WriteLine("廣度遍歷");
graph.bfs(0);

結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章