学数据结构学到图,把图的操作整理成类,下面贴出代码。
基本操作:
1. 通过邻接矩阵创建图
2. 计算某个元素的入度、出度、度
3. 打印邻接矩阵
4. 深度优先DFS
5. 广度优先BFS
6. 最小生成树Prim算法
7. 访问元素
…
关键路径等其他操作后续会给出…
注:这些常见操作都是按照邻接矩阵来写的。邻接矩阵转换为邻接表还没来得及写,应该问题不大。后续会给出完整版。
以下是类成员
#ifndef graph_hpp
#define graph_hpp
#include <iostream>
template<class Type> //这棵树是存放最小生成树的
struct Tree
{
Type element;
int Vi;
};
struct Aedge ////用于prim算法的辅助数组
{
int Vi; //顶点序号
int Wi; //邻接边的最小权值
};
template<class T1>
class Graph_with_list;
template <class T1>
class Graph_with_matrix {
private:
int vertex_num;
int edge_num;
int **matrix;
T1 *element; //数据元素
int First_AdjVex(int v); //返回第一个邻接点
int Next_AdjVex(int v,int w); //返回下一个邻接点
void Visit(T1 v); //访问的是元素而不是元素的位置
void DFS(int v,bool* visited); //递归函数,被DFS Traverse 调用
public:
Graph_with_matrix():vertex_num(0),edge_num(0),matrix(NULL),element(NULL){};
~Graph_with_matrix();
void Create_Graph(); //创建图
Tree<T1>* Prim(T1 start); //prim算法,用于生成最小生成树
void DFS_Traverse();
void BFS_Traverse();
void Print_matrix(); //打印邻接矩阵
// Graph_with_list<T1> Convert_to_list(); //转换为邻接表,后续给出
int ID(T1 e); //入度
int OD(T1 e); //出度
int TD(T1 e); //度
};
以下是实现的代码
#include "graph.hpp"
#include <queue>
using namespace std;
template<class T1>
void Graph_with_matrix<T1>::Create_Graph()
{
cout<<"Please input the elements :"<<endl;
element=new T1[20]; //为了节省空间,只使用20个
T1 in;
while (cin>>in&&in!='#') {
element[vertex_num]=in;
vertex_num++;
}
cin.clear();
cin.ignore(1,'\n');
cout<<"Please input the weight of edges: "<<endl;
int weight;
matrix=new int*[vertex_num];
for (int i=0; i<vertex_num; i++) {
matrix[i]=new int[vertex_num];
}
for (int i=0; i<vertex_num; i++) {
for (int j=0; j<vertex_num; j++) {
cin>>weight;
matrix[i][j]=weight;
if (weight!=0) {
edge_num++;
}
}
}
}
template<class T1>
void Graph_with_matrix<T1>::Print_matrix()
{
for (int i=0; i<vertex_num; i++) {
cout<<element[i]<<" ";
}
cout<<endl;
for (int i=0; i<vertex_num; i++) {
for (int j=0; j<vertex_num; j++) {
cout<<matrix[i][j]<<" ";
}
cout<<endl;
}
}
template<class T1>
Tree<T1>* Graph_with_matrix<T1>::Prim(T1 start)
{
Aedge cost[vertex_num]; //辅助数组
Tree<T1>* tree=new Tree<T1>[vertex_num];
//定位start在哪里,并赋值给u,u在之后记录权值最小的位置
int u = 0;
for (int i=0; i<vertex_num; i++) {
if (element[i]==start) {
u=i;
break;
}
}
tree[0].element=element[u];
tree[0].Vi=u;
int n=1; //记录tree的位置
//初始化辅助数组
for (int i=0; i<vertex_num; i++) {
(cost[i]).Wi=matrix[u][i];
cost[i].Vi=i;
}
cost[u].Wi=-1;
//开始遍历
for (int i=0; i<vertex_num-1; i++) {
//寻找辅助数组最小的值
int v=u; //记录u上次的值
u=0;
while (cost[u].Wi==0||cost[u].Wi==-1) { //找到第一个u,其weight不为0和-1
u++;
}
if (u==v) { //如果u等于u上次的值,则++
u++;
while (cost[u].Wi==0&&cost[u].Wi==-1) {
u++;
}
}
for (int j=u+1; j<vertex_num; j++) {
if ( cost[j].Wi!=0&&cost[j].Wi!=-1&&cost[u].Wi>cost[j].Wi) {
u=j;
}
}
tree[n].Vi=u;
tree[n].element=element[u];
n++;
cost[u].Wi=-1; //置为-1,表示不再用
//修改最小边值
for (int k=0; k<vertex_num; k++) {
if (matrix[u][k]<cost[k].Wi) {
cost[k].Wi=matrix[u][k];
cost[k].Vi=u;
}
else if (cost[k].Wi==0) {
cost[k].Wi=matrix[u][k];
cost[k].Vi=u;
}
}
}
cout<<"The tree will be like: "<<endl;
for (int i=0; i<vertex_num; i++) {
cout<<tree[i].element<<" "<<tree[i].Vi<<" "<<endl;
}
return tree;
}
//以下几个都是深度和广度遍历的函数
template<class T1>
void Graph_with_matrix<T1>::Visit(T1 v)
{
cout<<v<<" ";
}
template<class T1>
int Graph_with_matrix<T1>::First_AdjVex(int v)
{
for (int i=0; i<vertex_num; i++) {
if (matrix[v][i]&&i!=v) {
return i;
}
}
return -1; //不存在
}
template<class T1>
int Graph_with_matrix<T1>::Next_AdjVex(int v,int w)
{
for (int i=w+1; i<vertex_num; i++) {
if (matrix[v][i]&&i!=v) {
return i;
}
}
return -1;
}
template<class T1>
void Graph_with_matrix<T1>::DFS(int v,bool* visited)
{
int w;
visited[v]=true;
Visit(element[v]);
for (w=First_AdjVex(v); w>=0; w=Next_AdjVex(v, w)) {
if (!visited[w]) {
DFS(w);
}
}
}
template<class T1>
void Graph_with_matrix<T1>::DFS_Traverse()
{
int v;
bool* visited=new bool[vertex_num];
for (int i=0; i<vertex_num; i++) { //对访问标记初始化
visited[i]=false;
}
for (v=0; v<vertex_num; v++) {
if (!visited[v]) {
DFS(v,visited);
}
}
delete []visited;
}
template<class T1>
void Graph_with_matrix<T1>::BFS_Traverse()
{
int v,w;
bool *visited=new bool[vertex_num];
queue<int> q;
for (v=0; v<vertex_num; v++) { //初始化访问标记
visited[v]=false;
}
for (v=0; v<vertex_num; v++) {
if (!visited[v]) {
visited[v]=true;
Visit(element[v]);
q.push(v);
while (!q.empty()) {
q.pop();
for (w=First_AdjVex(v); w>=0; w=Next_AdjVex(v, w)) {
if (!visited[w]) {
visited[w]=true;
Visit(element[w]);
q.push(w);
}
}
}
}
}
delete []visited;
}
template<class T1>
Graph_with_matrix<T1>::~Graph_with_matrix()
{
//删除matrix
for (int i=0; i<vertex_num; i++) {
delete []matrix[i];
}
delete []matrix;
//删除element
delete []element;
}
template<class T1>
int Graph_with_matrix<T1>::OD(T1 e)
{
int od=0;
int u=-1;
for (int i=0; i<vertex_num; i++) { //找到
if (element[i]==e) {
u=i;
break;
}
}
if (u==-1) {
return -1; //表示找不到此元素
}
for (int i=0; i<vertex_num; i++) {
if (!matrix[u][i]) {
od++;
}
}
return od;
}
template<class T1>
int Graph_with_matrix<T1>::ID(T1 e)
{
int id=0;
int u=-1;
for (int i=0; i<vertex_num; i++) {
if (element[i]==e) {
u=i;
break;
}
}
if (u==-1) {
return -1;
}
for (int i=0; i<vertex_num; i++) { //按列找
if (!matrix[i][u]) {
id++;
}
}
return id;
}
template<class T1>
int Graph_with_matrix<T1>::TD(T1 e)
{
return ID(e)+OD(e);
}
第一次写,还有些稚嫩,欢迎大家提出意见,有任何代码上的问题随时可以联系我。