#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);
}
}
数据结构-有向图(邻接表)(c++实现)
于 2022-05-06 21:39:29 首次发布