1. 程式人生 > >圖的儲存(鄰接表)建立與深度優先、廣度優先搜尋

圖的儲存(鄰接表)建立與深度優先、廣度優先搜尋

#pragma once
#include<iostream>
#include<queue>
using namespace std;
#define Vnum 10
typedef int DATA;
/*鄰接表儲存圖*/
typedef struct list		//儲存連結串列的結構
{
	int weight;		//邊
	int index;		//頂點陣列的索引
	struct list *nextList;	//連結串列的下一個節點
}LIST;

typedef struct vex
{
	DATA data;			//頂點需要儲存的資料
	LIST * firstList;	//指向連結串列的第一個節點
} VEX;

class CGraph
{
private:
	bool visited[Vnum];	//標記索引為Vnum的頂點是否被訪問
	VEX vex[Vnum];	//以鄰接表的形式儲存整個圖的資訊
public:
	CGraph()	//圖物件在建立的時候的自動初始化
	{
		for(int i =0; i < Vnum; i++)
		{
			vex[i] = {};
			visited[i] = false;
		}
	}

	void CreateGraph()	//圖的建立,即鄰接表的建立
	{
		for(int i = 0; i < Vnum; i++)
		{
			int v = 0, weight = 0;
			vex[i].firstList = new LIST;
			LIST *temp = vex[i].firstList;
			cout << "輸入與第" << i << "個頂點相連的頂點與對應邊" << endl;
			cin >> v >> weight;
			temp->index = v;
			temp->weight = weight;
			while( v != -1)
			{
				cout << "再次輸入與第" << i << "個頂點相連的頂點與對應邊" << endl;
				cin >> v >> weight;
				if(v != -1)
				{
					temp->nextList = new LIST;
					temp = temp->nextList;
					temp->index = v;
					temp->weight = weight;
				}
				else
				{
					temp->nextList = NULL;
				}
			}

		}
		int a = 0;
	}

	void DFS( int v)	//深度優先搜尋
	{
		LIST *p = vex[v].firstList;
		cout << v << endl;
		visited[v] = true;
		while (p)	//列出所有狀態轉換的可能性
		{
			if (!visited[p->index])	//如果此狀態可轉換
			{
				DFS(p->index);	//遞迴進下一層深度
			}
			p = p->nextList;	//轉換到下一狀態
		}
	}
	void BFS(int v)		//廣度優先搜尋
	{
		cout << v << endl;
		LIST *p = vex[v].firstList;
		queue<LIST*> q;	
		q.push(p);	//先把初始頂點對應的連結串列第一節點放進佇列,使其不空佇列
		LIST *temp = p;	
		while(!q.empty())	//每進行一次大迴圈,會把當前頂點對應的所有未訪問過連結串列節點指標放入佇列
		{
			while(temp->nextList)
			{
				if (!visited[temp->nextList->index])
				{
					q.push(temp->nextList);
					visited[temp->nextList->index] = true;
				}
				temp = temp->nextList;
			}
			cout << q.front()->index << endl;	//然後輸出(一個)最先放進去的也就是最前面的資料資訊。
			temp = vex[q.front()->index].firstList;	//此頂點所連線的所有點已經訪問完畢,開始訪問其他排隊在前面的沒訪問過的節點
			q.pop();	//訪問到它了,可以出隊了
		}
	}
	~CGraph()	//物件銷燬時順便清理連結串列空間
	{
		for(int i = 0; i < Vnum; i++)
		{
			LIST *p = vex[i].firstList;
			LIST *temp = NULL;
			while(p)
			{
				temp = p->nextList;
				delete p;
				p = temp;
			}
		}
	}
};