比较简单的实现,图采用邻接矩阵的存储方式,且没有加上复制构造函数和重载运算符。
#include <iostream>
#include<stdexcept>
#include<stdio.h>
using namespace std;
struct Node
{
int data;
Node *next;
Node(){next=NULL;}
Node(int item,Node *link=NULL)
{
data=item;
next=link;
}
};
class LinkQueue
{
protected:
Node *front,*rear;
int count;
public:
LinkQueue(){rear=front=new Node();count=0;}
virtual ~LinkQueue();
int length()const{return count;}
bool Empty()const{return count==0;}
void Clear();
void Traverse()const;
bool OutQueue(int &e);
bool GetHead(int &e)const;
bool InQueue(const int &e);
LinkQueue(const LinkQueue ©);
LinkQueue&operator=(const LinkQueue ©);
};
LinkQueue::~LinkQueue()
{
Clear();
}
void LinkQueue::Clear()
{
int tmp;
while(!Empty())
OutQueue(tmp);
}
void LinkQueue::Traverse()const
{
for(Node *tmp=front->next;tmp!=NULL;tmp=tmp->next)
cout<<tmp->data<<' ';
}
bool LinkQueue::OutQueue(int &e)
{
if(!Empty())
{
Node *tmp=front->next;
e=tmp->data;
front->next=tmp->next;
if(rear==tmp)
rear=front;
delete tmp;
count--;
return true;
}
else
return false;
}
bool LinkQueue::GetHead(int &e)const
{
if(!Empty())
{
Node *tmp=front->next;
e=tmp->data;
return true;
}
else
return false;
}
bool LinkQueue::InQueue(const int &e)
{
Node *tmp=new Node(e);
rear->next=tmp;
rear=tmp;
count++;
return true;
}
LinkQueue::LinkQueue(const LinkQueue©)
{
rear=front=new Node();
count=0;
for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next)
InQueue(tmp->data);
}
LinkQueue&LinkQueue::operator=(const LinkQueue©)
{
if(©!=this)
{
Clear();
for(Node *tmp=copy.front->next;tmp!=NULL;tmp=tmp->next)
InQueue(tmp->data);
}
return *this;
}
class AdjMatrixDirGraph
{
protected:
int vexNum,edgeNum; //顶点数和边数
int **Matrix; //领接矩阵
int *elems; //顶点元素
mutable bool *tag; //指向标志数组的指针
void DestroyHelp(); //销毁有向图
void DFS(int v)const; //从顶点v开始深度优先遍历
void BFS(int v)const; //从顶点v开始广度优先遍历
public:
AdjMatrixDirGraph(int es[],int vertexNum=10); //构造数据元素为es,顶点个数为vertexNum,边数为0的有向图
AdjMatrixDirGraph(int vertexNum=10); //构造顶点个数为vertexNum变数为0的有向图
~AdjMatrixDirGraph(); //析构函数
void DFSTraverse()const; //对图进行深度优先遍历
void BFSTraverse()const; //对图进行广度优先遍历
bool GetElem(int v,int &e)const; //求顶点的元素
bool SetElem(int v,const int &e); //设置顶点的元素
int GetVexNum()const{return vexNum;} //返回顶点个数
int GetEdgeNum()const{return edgeNum;} //返回边的条数
int FirstAdjVex(int v)const; //返回顶点v的第一个邻接顶点
int NextAdjVex(int v1,int v2)const; //返回顶点v1的相对于v2的下一个邻接点
void InsertEdge(int v1,int v2); //插入顶点为v1和v2的边
void DeleteEdge(int v1,int v2); //删除顶点为v1和v2的边
bool GetTag(int v)const; //返回顶点v的标志
void SetTag(int v,bool val)const; //设置v1的标志为val
void Display()const; //显示关系矩阵
};
void AdjMatrixDirGraph::DestroyHelp()
{
delete[] elems;
delete[] tag;
for(int i=0;i<vexNum;i++)
delete []Matrix[i];
delete []Matrix;
}
void AdjMatrixDirGraph::DFS(int v)const
{
SetTag(v,true);
int e;
GetElem(v,e);
cout<<e<<' ';
for(int w=FirstAdjVex(v);w>=0;w=NextAdjVex(v,w))
if(!GetTag(w))
DFS(w);
}
void AdjMatrixDirGraph::DFSTraverse()const
{
int v;
for(v=0;v<GetVexNum();v++)
SetTag(v,false);
cout<<"深度遍历:";
for(v=0;v<GetVexNum();v++)
if(!GetTag(v))
DFS(v);
}
void AdjMatrixDirGraph::BFS(int v)const
{
SetTag(v,true);
int e;
GetElem(v,e);
cout<<e<<' ';
LinkQueue q;
q.InQueue(v);
while(!q.Empty())
{
int u,w;
q.OutQueue(u);
for(w=FirstAdjVex(u);w>=0;w=NextAdjVex(u,w))
{
if(!GetTag(w))
{
SetTag(w,true);
GetElem(w,e);
cout<<e<<' ';
q.InQueue(w);
}
}
}
}
void AdjMatrixDirGraph::BFSTraverse()const
{
int v;
for(v=0;v<vexNum;v++)
SetTag(v,false);
cout<<"广度遍历:";
for(v=0;v<vexNum;v++)
if(!GetTag(v))
BFS(v);
}
AdjMatrixDirGraph::AdjMatrixDirGraph(int es[],int vetexNum)
{
if(vetexNum<=0)
throw runtime_error("顶点数不能小于等于0");
vexNum=vetexNum,edgeNum=0;
Matrix=new int*[vexNum];
elems=new int[vexNum];
tag=new bool[vexNum];
for(int i=0;i<vexNum;i++)
Matrix[i]=new int[vexNum];
for (int u = 0; u < vexNum; u++)
for (int v = 0; v < vexNum; v++)
Matrix[u][v] = 0;
for(int i=0;i<vexNum;i++)
elems[i]=es[i];
for(int i=0;i<vexNum;i++)
tag[i]=false;
}
AdjMatrixDirGraph::AdjMatrixDirGraph(int vetexNum)
{
if(vetexNum<0)
throw runtime_error("顶点数不能小于等于0");
vexNum=vetexNum,edgeNum=0;
Matrix=new int*[vexNum];
elems=new int[vexNum];
tag=new bool[vexNum];
for(int i=0;i<vexNum;i++)
Matrix[i]=new int[vexNum];
for (int u = 0; u < vexNum; u++)
for (int v = 0; v < vexNum; v++)
Matrix[u][v] = 0;
for(int i=0;i<vexNum;i++)
tag[i]=false;
}
AdjMatrixDirGraph::~AdjMatrixDirGraph()
{
DestroyHelp();
}
bool AdjMatrixDirGraph::GetElem(int v,int &e)const
{
if(v<0||v>=vexNum)
return false;
else
{
e=elems[v];
return true;
}
}
bool AdjMatrixDirGraph::SetElem(int v,const int &e)
{
if(v<0||v>=vexNum)
return false;
else
{
elems[v]=e;
return true;
}
}
int AdjMatrixDirGraph::FirstAdjVex(int v)const
{
int i=0;
while(Matrix[v][i]==0&&i<vexNum)
i++;
if(Matrix[v][i]==1)
return i;
return -1;
}
int AdjMatrixDirGraph::NextAdjVex(int v1,int v2)const
{
while(Matrix[v1][++v2]==0&&v2<vexNum)
if(Matrix[v1][v2]==1)
return v2;
return -1;
}
void AdjMatrixDirGraph::InsertEdge(int v1,int v2)
{
if(v1<0||v1>=vexNum) throw runtime_error("v1不合法");
if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!");
if(v1==v2) throw runtime_error("v1不能等于v2!");
if(Matrix[v1][v2]==0&&Matrix[v2][v1]==0)
edgeNum++;
Matrix[v1][v2]=1;
Matrix[v2][v1]=1;
}
void AdjMatrixDirGraph::DeleteEdge(int v1,int v2)
{
if(v1<0||v1>=vexNum) throw runtime_error("v1不合法!");
if(v2<0||v2>=vexNum) throw runtime_error("v2不合法!");
if(v1==v2) throw runtime_error("v1不能等于v2!");
if(Matrix[v1][v2]==1&&Matrix[v2][v1]==1)
edgeNum--;
Matrix[v1][v2]=0;
Matrix[v2][v1]=0;
}
bool AdjMatrixDirGraph::GetTag(int v)const
{
if(v<0||v>=vexNum)
throw runtime_error("v不合法");
else
return tag[v];
}
void AdjMatrixDirGraph::SetTag(int v,bool val)const
{
if(v<0||v>=vexNum)
throw runtime_error("v不合法");
else
tag[v]=val;
}
void AdjMatrixDirGraph::Display()const
{
for(int i=0;i<vexNum;i++)
{
for(int j=0;j<vexNum;j++)
cout<<Matrix[i][j]<<' ';
cout<<endl;
}
}
int main()
{
int vetexNum,edgeNum,v1,v2;
cout<<"请输入顶点个数:";
cin>>vetexNum;
int es[vetexNum];
for(int i=0;i<vetexNum;i++)
{
cout<<"请输入顶点编号为"<<i<<"的顶点的值:";
cin>>es[i];
}
AdjMatrixDirGraph g(es,vetexNum);
cout<<"请输入边的条数:";
cin>>edgeNum;
for(int i=0;i<edgeNum;i++)
{
cout<<"请输入所要插入的第"<<i+1<<"条边的两个端点(以空格隔开):";
scanf("%d %d",&v1,&v2);
g.InsertEdge(v1,v2);
}
g.Display();
g.DFSTraverse();
g.BFSTraverse();
return 0;
}