邻接矩阵存储图的两种遍历方式

下面是用邻接矩阵存储一个无向图的深度优先遍历和广度优先遍历代码,深度优先遍历就是树的先根遍历的一种推广,而广度优先也是和树的层次遍历相似的,用邻接矩阵存储,进行这两种遍历的实现,是比较容易的。

因为用了自己写的循环队列的模版,所以代码看起来有点冗长.

#include<iostream>
#include<string>
using namespace std;

//下面是循环队列模版
template<class T>
class My_queue;

template<class T>
class Node
{
private:
	T data;
	Node<T> *next;
public:
	Node()
	{
		next=0;
	}
	Node(T d)
	{
		data=d;
		next=0;
	}
	friend My_queue<T>;
};

template<class T>
class My_queue
{
private:
	Node<T> *tail;
public:
	My_queue()
	{
		tail=new Node<T>();
		tail->next=tail;
	}

	~My_queue()
	{
		clean();
		delete tail;
	}

	bool empty()
	{
		return (tail->next==tail);
	}

	void push(T d)
	{
		Node<T> *p=new Node<T>(d);
		p->next=tail->next;
		tail->next=p;
		tail=p;
	}

	T front()
	{
		if(empty())
		{
			cout<<"queue is empty!"<<endl;
			exit(0);
		}
		Node<T> *p=tail->next;
		T data=p->next->data;
		return data;
	}

	T back()
	{
		if(empty())
		{
			cout<<"queue is empty!"<<endl;
			exit(0);
		}
		T data=tail->data;
		return data;
	}

	void pop()
	{
		Node<T> *p=tail->next;
		Node<T> *q=p->next;
		p->next=q->next;
		if(q==tail)
			tail=p;
		delete q;
	}

	void clean()
	{
		Node<T> *p=tail->next;
		Node<T> *q=p->next;
		while(q!=p)
		{
			p->next=q->next;
			delete q;
			p->next=q;
		}
	}
};

#define MAX_VERTEX_NUM 20

bool visited[20];//全局数组,用于辅助遍历

struct MGraph
{
	string vexs[MAX_VERTEX_NUM];//顶点数组
	int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
	int vexnum;//顶点数目
	int arcnum;//边数目
};

int Locate_Vex(MGraph G,string x)  //用于确定顶点在顶点数组中的位置
{
	for(int k=0;G.vexs[k]!=x;k++);
	return k;
}

void CreateUDN_MG(MGraph &G)
{
	//采用邻接矩阵表示法,构造无向图
	int i,j,k;
	cout<<"输入图的顶点数和边数:";
	cin>>G.vexnum>>G.arcnum;
	cout<<"输入各个顶点的民称:";
	for(i=0;i<G.vexnum;i++)
		cin>>G.vexs[i];
	
	for(i=0;i<G.vexnum;i++)
		for(int j=0;j<G.vexnum;j++)
			G.arcs[i][j]=0;
	//上面是初始化邻接矩阵
	
	for(k=0;k<G.arcnum;k++)
	{
		cout<<"输入每条边对应的两个顶点:";
		string v1,v2;
		cin>>v1>>v2;
		i=Locate_Vex(G,v1);
		j=Locate_Vex(G,v2);
		while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1)
		{
			cout<<"结点位置输入错误,重新输入: ";
			cin>>v1>>v2;
			i=Locate_Vex(G,v1);
			j=Locate_Vex(G,v2);	
		}
		G.arcs[i][j]=1;
		G.arcs[j][i]=G.arcs[i][j]; //置对称边
	}
	cout<<"图构造完成"<<endl;
}

void DFS(MGraph G,int v)
{
	visited[v]=true;
	cout<<G.vexs[v]<<"  ";
	for(int j=0;j<G.vexnum;j++)
		if(G.arcs[v][j] && !visited[j])
			DFS(G,j);
}

//深度优先遍历图
void DFS_Traverse(MGraph G)
{
	//visited数组用来作为是否已访问的标志
	for(int i=0;i<G.vexnum;i++)
		visited[i]=false;
	for(int v=0;v<G.vexnum;v++)
		if(!visited[v])
			DFS(G,v);
}

//广度优先遍历
void BFS_Traverse(MGraph G)
{
	My_queue<int> q;
	int u,w,v;
	for(v=0;v<G.vexnum;v++)
		visited[v]=false;
	for(v=0;v<G.vexnum;v++)
		if(!visited[v])
		{
			visited[v]=true;
			cout<<G.vexs[v]<<"  ";
			q.push(v);
			while(!q.empty())
			{
				u=q.front();
				q.pop();
				for(w=0;w<G.vexnum;w++)
					if(G.arcs[u][w] && !visited[w])
					{
						visited[w]=true;
						cout<<G.vexs[w]<<"  ";
						q.push(w);
					}
			}
		}
}
	
int main()
{
	MGraph G;
	CreateUDN_MG(G);
	cout<<"深度优先遍历图为:";
	DFS_Traverse(G);
	cout<<endl;
	cout<<"广度优先遍历图为:";
	BFS_Traverse(G);
	cout<<endl;
	return 0;
}

测试结果:

输入图的顶点数和边数:8 9
输入各个顶点的民称:v1 v2 v3 v4 v5 v6 v7 v8
输入每条边对应的两个顶点:v1 v2
输入每条边对应的两个顶点:v1 v3
输入每条边对应的两个顶点:v2 v4
输入每条边对应的两个顶点:v2 v5
输入每条边对应的两个顶点:v4 v8
输入每条边对应的两个顶点:v5 v8
输入每条边对应的两个顶点:v3 v6
输入每条边对应的两个顶点:v3 v7
输入每条边对应的两个顶点:v6 v7
图构造完成
深度优先遍历图为:v1  v2  v4  v8  v5  v3  v6  v7
广度优先遍历图为:v1  v2  v3  v4  v5  v6  v7  v8
Press any key to continue

按照上面的输入所生产的图如下所示:


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值