数据结构-有向图(邻接表)(c++实现)

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

//有向图的邻接表表示法及深度遍历和广度遍历

//弧结点
class node
{
public:
	node(int num);
	~node();

	int index;		//在顶点表中的下标

	node* out;		//出度结点

};

//构造
node::node(int num) { index = num; out = nullptr; }

//析构
node::~node() { index = 0; out = nullptr; }


//表元素
template<class T>
class table
{
public:
	table();
	table(T _data);
	~table();

	T data;

	node* out;
};

template<class T>		//有参构造
table<T>::table(T _data) { data = _data; out = nullptr; }


template<class T>		//无参构造
table<T>::table() { data = NULL; out = nullptr; }


template<class T>		//析构
table<T>::~table() { data = NULL; out = nullptr; }



//图
template<class T>
class map
{
public:
	map(T _data[],int len);
	~map();

	void print();						//打印所有边结点

	void DFS(int _index);				//深度优先遍历

	void BFS(int _index);				//广度优先遍历



private:

	void dfs(int _index,bool* arr);								//深度遍历

	void bfs(int _index,bool* arr,queue<int>& Q);				//广度遍历

	table<T>* M;			//顶点表

	int length;				//表长

};


template<class T>			//图的邻接表构造
map<T>::map(T data[],int len) 
{
	length = len - 1;

	M = new table<T>[length];

	for(int i = 0; i < length;i++)
	{
		M[i].data = data[i];
	}

	//建立弧
	cout << "请输入弧的数量:";

	int num;
	cin >> num;

	if (num < 0 || num > length * (length - 1)) { cout << "数量有误!" << endl; return; }

	for (int i = 0; i < num; i++)
	{
		cout << "请输入弧尾元素的位置:";
		int k, z;
		cin >> k;
		cout << "请输入弧头元素的位置:";
		cin >> z;

		if (M[k].out == nullptr) 
		{ 
			node* p = new node(z);
			M[k].out = p; 
		}
		else
		{
			node* p = new node(z);
			node* temp = M[k].out;
			bool flag = true;
			while (flag)
			{
				if (temp->out != nullptr) { temp = temp->out; }
				else { flag = false; }
			}
			temp->out = p;
		}
	}
}


template<class T>		//析构
map<T>::~map() 
{

	//释放弧结点
	for (int i = 0; i < length; i++)
	{
		if (M[i].out != nullptr)
		{
			node* temp = M[i].out;
			node* _temp = nullptr;
			bool flag = true;
			while (flag)
			{
				if (temp->out != nullptr)
				{
					_temp = temp->out;
					delete temp;
					temp = _temp;
				}
				else
				{
					delete temp;
					temp = nullptr;
					flag = false;
				}
			}
			_temp = nullptr;
		}
	}

	//释放顶点表
	delete[]M;			
	M = nullptr;		
	length = 0;
}


template<class T>		//遍历所有元素及它的出度弧
void map<T>::print()
{
	for (int i = 0; i < length; i++)
	{
		cout << "弧尾元素: " << M[i].data << "\t\t" << "弧头结点下标为:";
		if(M[i].out != nullptr)
		{ 
			node* p = M[i].out; 
		
			bool flag = true;
			while (flag)
			{
				if (p->out != nullptr)
				{
					cout << p->index << "  ";		
					p = p->out;
				}
				else { cout << p->index << "  "; flag = false; }
			}
		}
		cout << endl;
	}
}

template<class T>			//深度优先搜索遍历
void map<T>::DFS(int _index) 
{
	bool* arr = new bool[length];
	for (int i = 0; i < length; i++) { arr[i] = false; }
	dfs(_index,arr);

	//非连通图的遍历补充 -- 此处为按元素位置遍历 -- 可根据需求自行修改遍历规则

	for (int i = 0; i < length; i++) { if (arr[i] == false) { dfs(i, arr); } }		

	cout << endl;
    
    delete[]arr;
    arr = nullptr;
}


template<class T>			//深度优先遍历递归实现
void map<T>::dfs(int _index,bool* arr) 
{
	if (arr[_index] == false)
	{
		cout << M[_index].data << " ";

		arr[_index] = true;

		if (M[_index].out != nullptr) 
		{
			node* temp = M[_index].out;

			dfs(temp->index, arr);
			
			if (temp->out != nullptr) { temp = temp->out; dfs(temp->index, arr); }
		}
	}
}


template<class T>			//广度优先搜索遍历
void map<T>::BFS(int _index)
{
	bool* arr = new bool[length];

	for (int i = 0; i < length; i++) { arr[i] = false; }

	queue<int> Q;

	bfs(_index,arr,Q);

	//非连通图的遍历补充 -- 此处为按元素位置遍历 -- 可根据需求自行修改遍历规则

	for (int i = 0; i < length; i++) { if (arr[i] == false) { bfs(i, arr, Q); } }	

	cout << endl;
    delete[]arr;
    arr = nullptr;
}


template<class T>			//广度优先搜索遍历递归实现
void map<T>::bfs(int _index,bool* arr,queue<int>& Q) 
{
	if (arr[_index] == false)
	{
		cout << M[_index].data << " ";

		arr[_index] = true;

		if (M[_index].out != nullptr)
		{
			node* temp = M[_index].out;

			bool flag = true;

			while (flag)
			{
				Q.push(temp->index);
				if (temp->out != nullptr) { temp = temp->out; }
				else { flag = false; }
			}
		}
	}
	if (!Q.empty())
	{
		int ret = Q.front();
		Q.pop();
		bfs(ret, arr, Q);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心若雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值