C++ Exercises(十七)--图的简单实现

本文介绍了一种通用图类的实现,该图类支持顶点和边的操作,并提供了深度优先搜索和广度优先搜索的功能。通过示例代码展示了如何创建图、添加顶点与边,以及进行图的遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->constintMAXSIZE=50;//顶点最大数目

#include
<vector>
usingnamespacestd;

template
<typenameT>
classCGraph
ExpandedBlockStart.gifContractedBlock.gif
{
public:
CGraph(
void);
~CGraph(void);
private:
vector
<T>vecNodes;//顶点列表
intedge[MAXSIZE][MAXSIZE];//边表
intnumVertexs;//顶点数
intnumEdges;//边数
boolvisited[MAXSIZE];//用于图的遍历

intFindVertex(constT&vertex,constvector<T>&lst);
voidClearVisitFlag();
vector
<T>&GraphDepthFirstSearch(constT&beginVertex);//深度遍历图
vector<T>&GraphBreadthFirstSearch();//广度遍历

public:
boolGraphEmpty(void)const;
boolGraphFull(void)const;
intNumberOfVertices(void)const;//获取顶点数
intNumberOfEdges(void)const;//获取边数
intGetWeight(constT&vertex1,constT&vertex2);//获取指定两个顶点间的权值
vector<T>&GetNeighbors(constT&vertex);//获取指定顶点的邻接顶点

voidCreateGraph();//创建图
intGetVertexPos(constT&vertex);//获取指定顶点的位置

intInsertVertex(constT&vertex);//插入顶点
voidInsertEdge(constT&vertex1,constT&vertex2,intweight);//插入边
voidDeleteVertex(constT&vertex);//删除顶点
voidDeleteEdge(constT&vertex1,constT&vertex2);//删除边

//intMinimumPath(constT&sVertex,constT&desVertex);最短路径
voidDepthFirstSearch();//深度遍历图
voidBreadthFirstSearch();//广度遍历图
}
;

ContractedBlock.gifExpandedBlockStart.gif图的实现代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"Graph.h"
#include
<stack>
#include
<queue>
#include
<algorithm>
#include
<iostream>

usingnamespacestd;

template
<typenameT>
CGraph
<T>::CGraph(void)
ExpandedBlockStart.gifContractedBlock.gif
{
for(inti=0;i<MAXSIZE;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
for(intj=0;j<MAXSIZE;++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->edge[i][j]=0;
}

}

this->numVertexs=0;
this->numEdges=0;
}

template
<typenameT>
CGraph
<T>::~CGraph(void)
ExpandedBlockStart.gifContractedBlock.gif
{
this->vecNodes.clear();
for(inti=0;i<MAXSIZE;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
for(intj=0;j<MAXSIZE;++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->edge[i][j]=0;
}

}

this->numVertexs=0;
this->numEdges=0;
}

template
<typenameT>
intCGraph<T>::NumberOfEdges()const
ExpandedBlockStart.gifContractedBlock.gif
{
returnthis->numEdges;
}

template
<typenameT>
intCGraph<T>::NumberOfVertices()const
ExpandedBlockStart.gifContractedBlock.gif
{
returnthis->numVertexs;
}

template
<typenameT>
intCGraph<T>::GetWeight(constT&vertex1,constT&vertex2)
ExpandedBlockStart.gifContractedBlock.gif
{
intpos1,pos2;
pos1
=this->GetVertexPos(vertex1);
pos2
=this->GetVertexPos(vertex2);
returnthis->edge[pos1][pos2];
}

template
<typenameT>
boolCGraph<T>::GraphFull()const
ExpandedBlockStart.gifContractedBlock.gif
{
returnthis->numVertexs>=MAXSIZE;
}

template
<typenameT>
boolCGraph<T>::GraphEmpty()const
ExpandedBlockStart.gifContractedBlock.gif
{
returnthis->numVertexs==0;
}

template
<typenameT>
intCGraph<T>::InsertVertex(constT&vertex)
ExpandedBlockStart.gifContractedBlock.gif
{//插入顶点,返回插入位置
intresult=-1;
if(!this->GraphFull())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->vecNodes.push_back(vertex);
result
=this->numVertexs;
this->numVertexs++;
}

}

template
<typenameT>
voidCGraph<T>::InsertEdge(constT&vertex1,constT&vertex2,intweight)
ExpandedBlockStart.gifContractedBlock.gif
{//插入边
intpos1,pos2;
pos1
=this->GetVertexPos(vertex1);
pos2
=this->GetVertexPos(vertex2);
if(pos1==-1&&pos2==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{//两个都是新顶点
pos1=this->InsertVertex(vertex1);
pos2
=this->InsertVertex(vertex2);

}

elseif(pos1==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{//一个是新顶点
pos1=this->InsertVertex(vertex1);
}

elseif(pos2==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pos2
=this->InsertVertex(vertex2);
}

this->edge[pos1][pos2]=weight;
this->edge[pos2][pos1]=weight;
}

template
<typenameT>
voidCGraph<T>::DeleteVertex(constT&vertex)
ExpandedBlockStart.gifContractedBlock.gif
{//删除顶点
intpos=this->GetVertexPos(vertex);
if(pos!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->vecNodes.erase(remove(this->vecNodes.begin(),this->vecNodes.end(),vertex),this->vecNodes.end());//删除顶点
for(inti=0;i<this->numVertexs;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this->edge[pos][i]>0)
this->edge[pos][i]=0;
if(this->edge[i][pos]>0)
this->edge[i][pos]=0;
}

this->numVertexs--;
this->numEdges--;
}

}

template
<typenameT>
voidCGraph<T>::DeleteEdge(constT&vertex1,constT&vertex2)
ExpandedBlockStart.gifContractedBlock.gif
{//删除边
intpos1,pos2;
pos1
=this->GetVertexPos(vertex1);
pos2
=this->GetVertexPos(vertex2);
if(pos1!=-1&&pos2!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this->edge[pos1][pos2]>0)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->edge[pos1][pos2]=0;
this->edge[pos2][pos1]=0;
this->numEdges--;
}

}

}


template
<typenameT>
voidCGraph<T>::CreateGraph()
ExpandedBlockStart.gifContractedBlock.gif
{//创建图
cout<<"输入顶点数,边数:";
cin
>>this->numVertexs;
cin
>>this->numEdges;

inti;
Titem;
cout
<<"输入顶点:";
for(i=0;i<this->numVertexs;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<""<<i+1<<"个顶点:";
cin
>>item;
this->vecNodes.push_back(item);
}

Tvert1,vert2;
intpos1,pos2,weight;
for(i=0;i<this->numEdges;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<"输入第"<<i+1<<"条边(尾,头,权值):";
cin
>>vert1>>vert2>>weight;
pos1
=this->GetVertexPos(vert1);
pos2
=this->GetVertexPos(vert2);
this->edge[pos1][pos2]=weight;
this->edge[pos2][pos1]=weight;
}

}

template
<typenameT>
intCGraph<T>::GetVertexPos(constT&vertex)
ExpandedBlockStart.gifContractedBlock.gif
{//获取顶点位置
returnthis->FindVertex(vertex,this->vecNodes);
}

template
<typenameT>
intCGraph<T>::FindVertex(constT&vertex,constvector<T>&lst)
ExpandedBlockStart.gifContractedBlock.gif
{//在顶点列表中找指定数据的下标
intpos=-1;
for(pos=lst.size()-1;pos>=0;--pos)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(lst[pos]==vertex)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
break;
}

}

returnpos;
}


template
<typenameT>
vector
<T>&CGraph<T>::GraphDepthFirstSearch(constT&beginVertex)
ExpandedBlockStart.gifContractedBlock.gif
{//深度遍历
vector<T>*result=newvector<T>();
vector
<T>adjLst;
stack
<T>s;
s.push(beginVertex);
intpos;
Tvertex;
vector
<T>::iteratoriter;
while(!s.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
vertex
=s.top();
s.pop();
if(this->FindVertex(vertex,*result)==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pos
=this->GetVertexPos(vertex);
visited[pos]
=true;
(
*result).push_back(vertex);
adjLst
=this->GetNeighbors(vertex);
for(iter=adjLst.begin();iter!=adjLst.end();++iter)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this->FindVertex(*iter,*result)==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
s.push(
*iter);
}

}

}

}

return*result;
}

template
<typenameT>
voidCGraph<T>::ClearVisitFlag()
ExpandedBlockStart.gifContractedBlock.gif
{
for(inti=0;i<this->numEdges;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->visited[i]=false;
}

}

template
<typenameT>
voidCGraph<T>::BreadthFirstSearch()
ExpandedBlockStart.gifContractedBlock.gif
{
vector
<T>::const_iteratoriter;
vector
<int>vec;
this->ClearVisitFlag();
vec
=this->GraphBreadthFirstSearch();
for(iter=vec.begin();iter!=vec.end();++iter)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<*iter<<"";
}

this->ClearVisitFlag();
}


template
<typenameT>
vector
<T>&CGraph<T>::GraphBreadthFirstSearch()
ExpandedBlockStart.gifContractedBlock.gif
{//广度遍历
vector<T>*result=newvector<T>();
vector
<T>adjLst;
vector
<T>::iteratoriter;
queue
<T>q;
Titem;
intpos;
this->ClearVisitFlag();
for(inti=0;i<this->numVertexs;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(!this->visited[i])
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
visited[i]
=true;
result
->push_back(this->vecNodes[i]);

q.push(
this->vecNodes[i]);
while(!q.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
item
=q.front();
q.pop();
adjLst
=this->GetNeighbors(item);
for(iter=adjLst.begin();iter!=adjLst.end();++iter)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this->FindVertex(*iter,*result)==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
result
->push_back(*iter);
pos
=this->GetVertexPos(*iter);
visited[pos]
=true;
}

}

}

}

}

return*result;
}


template
<typenameT>
vector
<T>&CGraph<T>::GetNeighbors(constT&vertex)
ExpandedBlockStart.gifContractedBlock.gif
{//获取邻接顶点
vector<T>*result;
result
=newvector<T>();
intpos=this->GetVertexPos(vertex);
if(pos==-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cerr
<<"顶点不在图中"<<endl;
return*result;
}

for(inti=0;i<this->numVertexs;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(edge[pos][i]>0)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
result
->push_back(this->vecNodes[i]);
}

}

return*result;
}


template
<typenameT>
voidCGraph<T>::DepthFirstSearch()
ExpandedBlockStart.gifContractedBlock.gif
{
vector
<T>::const_iteratoriter,iter2;
intpos;
vector
<int>vec1;
this->ClearVisitFlag();
for(iter=this->vecNodes.begin();iter!=this->vecNodes.end();++iter)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pos
=this->GetVertexPos(*iter);
if(!visited[pos])
ExpandedSubBlockStart.gifContractedSubBlock.gif
{//还未访问,从这点开始
vec1=this->GraphDepthFirstSearch(*iter);
for(iter2=vec1.begin();iter2!=vec1.end();++iter2)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<*iter2<<"";
}

}

}

this->ClearVisitFlag();
}

测试程序:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"Graph.cpp"
#include
<iostream>
usingnamespacestd;


intmain(intargc,char*argv[])
ExpandedBlockStart.gifContractedBlock.gif
{

CGraph
<int>*graph1=newCGraph<int>();
graph1
->CreateGraph();
graph1
->DepthFirstSearch();
graph1
->BreadthFirstSearch();
system(
"pause");
return0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值