1. 程式人生 > >鄰接表與鄰接矩陣的深度優先演算法和廣度優先演算法

鄰接表與鄰接矩陣的深度優先演算法和廣度優先演算法

鄰接矩陣的深度優先演算法:

#include<iostream>
using namespace std;
#define MAX 20
// 注:鄰接矩陣是圖的順序儲存方式
typedef struct node
{
	int no; //頂點編號
			//	char data;	//頂點其它資訊,不常用
}VertexType;
typedef struct  //圖的定義
{
	int edges[MAX][MAX]; //鄰接矩陣定義
	int n, e;	//頂點數和邊數
	VertexType vex[MAX]; //存放節點資訊
}MGraph;
MGraph graph;
bool visited[MAX];//訪問過的標誌為true   未訪問的設定為false
void Create()
{
	cout << "輸入頂點數和邊數: ";
	cin >> graph.n >> graph.e;
	int N1 = graph.n, N2 = graph.e;
	for (int i = 0; i < N1; i++)
	{
		graph.vex[i].no = i;
	}

	for (int i = 0; i < N1; i++)//初始化edges陣列
		for (int j = 0; j < N1; j++)
			graph.edges[i][j] = 0;
	//給鄰接矩陣賦值
	for (int i = 0; i < N2; i++)
	{
		int v1, v2;
		cout << "v1,v2 = ";
		cin >> v1 >> v2;
		graph.edges[v1][v2] = 1;
	}
}
// 鄰接矩陣的深度遍歷操作
void DFS(int i)
{
	if (visited[i] == false)
	{
		visited[i] = true;
		cout << graph.vex[i].no << ' ';
		for (int j = 0; j < graph.n; j++)
		{
			if (graph.edges[i][j] == 1 && visited[j] == false) //如果 ij兩點可達,且j未被訪問過,就遞迴遍歷j
				DFS(j);
		}
	}
}
void DFSTraverse()
{
	for (int i = 0; i < graph.n; i++)//初始化將visited所有點設定為false
		visited[i] = false;
	for (int j = 0; j < graph.n; j++)
		DFS(j);
}
int main(void)
{
	Create();
	DFSTraverse();

	system("pause");
	return 0;
}

鄰接矩陣廣度優先演算法:
#include<iostream>
using namespace std;
#define MAX 20
// 注:鄰接矩陣是圖的順序儲存方式
typedef struct node
{
	int no; //頂點編號
			//	char data;	//頂點其它資訊,不常用
}VertexType;
typedef struct  //圖的定義
{
	int edges[MAX][MAX]; //鄰接矩陣定義
	int n, e;	//頂點數和邊數
	VertexType vex[MAX]; //存放節點資訊
}MGraph;

MGraph graph;
bool visited[MAX];//訪問過的標誌為true   未訪問的設定為false
void Create()
{
	cout << "輸入頂點數和邊數: ";
	cin >> graph.n >> graph.e;
	int N1 = graph.n, N2 = graph.e;
	for (int i = 0; i < N1; i++)
	{
		graph.vex[i].no = i;
	}

	for (int i = 0; i < N1; i++)//初始化edges陣列
		for (int j = 0; j < N1; j++)
			graph.edges[i][j] = 0;
	//給鄰接矩陣賦值
	for (int i = 0; i < N2; i++)
	{
		int v1, v2;
		cout << "v1,v2 = ";
		cin >> v1 >> v2;
		graph.edges[v1][v2] = 1;
	}
}
// 鄰接矩陣的廣度遍歷操作
//類似於二叉樹的按層遍歷
void BFS()
{
	for (int i = 0; i < graph.n; i++)//初始化visited陣列為false
		visited[i] = false;

	int queue[MAX];
	memset(queue, 0, sizeof(int)*MAX);
	int front = -1, rear = 0;

	queue[0] = graph.vex[0].no;//設定從0開始遍歷
	visited[0] = true;

	while (front != rear)
	{
		front++;
		cout << queue[front];
		for (int j = 0; j < graph.n; j++)
		{
			//如果二者相連且該點沒有被訪問過,將此點入隊
			if (graph.edges[queue[front]][j] == 1 && visited[j] == false)
			{
				queue[++rear] = j;
				visited[j] = true;
			}
		}
	}
}
int main(void)
{
	Create();
	BFS();

	system("pause");
	return 0;
}

鄰接表建立圖解:


鄰接表的深度優先演算法:
#include<iostream>
using namespace std;

#define MAX 20
typedef struct arcnode
{
	int adjvex; //該邊所指向的節點的位置
	struct arcnode* nextarc; //指向下一條邊的指標
							 //	int info;	//該邊的其它資訊,如權值等。
}ArcNODE; //表結點型別
typedef struct  vnode
{
	char data;//頂點資訊
	ArcNODE *firstarc; //指向第一條邊的指標
}VNode;//頭結點
typedef struct
{
	VNode adjust[MAX]; //鄰接表
	int n, e;// n為頂點數,e為邊數
}AGraph;
AGraph graph;
bool visited[MAX];
void Create()
{

	cout << "輸入頂點數和邊數";
	cin >> graph.n >> graph.e;
	for (int i = 0; i < graph.n; i++)//初始化鄰接表
	{
		graph.adjust[i].firstarc = (ArcNODE*)malloc(sizeof(ArcNODE));
		graph.adjust[i].firstarc->nextarc = NULL; //將第一個節點的next指標賦值為NULL
	}
	//建立鄰接表
	for (int i = 0; i < graph.n; i++)
	{
		int n;
		cout << "輸入" << i << "的頂點值";
		cin >> graph.adjust[i].data;
		cout << "輸入" << i << "的出度";
		cin >> n;
		ArcNODE *q = graph.adjust[i].firstarc;
		while (n)
		{
			int num;
			cin >> num;
			ArcNODE *p;
			p = (ArcNODE*)malloc(sizeof(ArcNODE));
			p->adjvex = num;
			q->nextarc = p;
			q = p;
			q->nextarc = NULL;
			n--;
		}
	}

}
void DFS(int i)
{
	if (visited[i] == 0)
	{
		visited[i] = 1;
		ArcNODE*p = graph.adjust[i].firstarc->nextarc;//p指向表頭節點
		cout << graph.adjust[i].data << ' ';
		while (p != NULL)
		{
			if (visited[p->adjvex] == 0) //由於表頭裡不存放值,所以判斷nextarc的值
				DFS(p->adjvex);
			p = p->nextarc;
		}
	}
}
void DFSTraverse()
{
	for (int v = 0; v<graph.n; ++v)
		visited[v] = 0;
	for (int v = 0; v<graph.n; ++v)
		if (visited[v] == 0)
			DFS(v);
}
int main(void)
{
	Create();
	for (int i = 0; i < graph.n; i++)
		DFS(i);
	system("pause");
	return 0;
}


鄰接表的廣度優先演算法:
#include<iostream>
using namespace std;

#define MAX 20
typedef struct arcnode
{
	int adjvex; //該邊所指向的節點的位置
	struct arcnode* nextarc; //指向下一條邊的指標
							 //	int info;	//該邊的其它資訊,如權值等。
}ArcNODE; //表結點型別
typedef struct  vnode
{
	char data;//頂點資訊
	ArcNODE *firstarc; //指向第一條邊的指標
}VNode;//頭結點
typedef struct
{
	VNode adjust[MAX]; //鄰接表
	int n, e;// n為頂點數,e為邊數
}AGraph;
AGraph graph;
bool visited[MAX];
void Create()
{

	cout << "輸入頂點數和邊數";
	cin >> graph.n >> graph.e;
	for (int i = 0; i < graph.n; i++)//初始化鄰接表
	{
		graph.adjust[i].firstarc = (ArcNODE*)malloc(sizeof(ArcNODE));
		graph.adjust[i].firstarc->nextarc = NULL; //將第一個節點的next指標賦值為NULL
	}
	//建立鄰接表
	for (int i = 0; i < graph.n; i++)
	{
		int n;
		cout << "輸入" << i << "的頂點值";
		cin >> graph.adjust[i].data;
		cout << "輸入" << i << "的出度";
		cin >> n;
		ArcNODE *q = graph.adjust[i].firstarc;
		while (n)
		{
			int num;
			cin >> num;
			ArcNODE *p;
			p = (ArcNODE*)malloc(sizeof(ArcNODE));
			p->adjvex = num;
			q->nextarc = p;
			q = p;
			q->nextarc = NULL;
			n--;
		}
	}

}
void BFS()
{
	for (int i = 0; i < graph.n; i++)//初始化visited陣列為false
		visited[i] = false;

	int queue[MAX];
	int front = -1, rear = 0;
	queue[0] = 0;
	visited[0] = true;
	while (front != rear)
	{
		front++;
		cout << graph.adjust[queue[front]].data;
		ArcNODE *p = graph.adjust[queue[front]].firstarc->nextarc;//p永遠指向佇列頭所代表的那個表頭節點的next
		while (p != NULL)
		{
			if (visited[p->adjvex] == 0)
			{
				visited[p->adjvex] = 1;
				queue[++rear] = p->adjvex;
			}
			p = p->nextarc;
		}
	}

}
int main(void)
{
	Create();
	BFS();
	system("pause");
	return 0;
}