(1)采用邻接矩阵/邻接表建立图;
(2)采用深度优先/广度优先搜索方式遍历图;
(3)编程实现Dijkstra最短路径算法。
#include <iostream>
using namespace std;
#define MaxInt 32767
#define MVNum 100
typedef struct{
char vexs[MVNum];
int arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
typedef struct ArcNode{
int adjvex;
struct ArcNode * nextarc;
}ArcNode;
typedef struct VNode{
char data;
ArcNode *firstarc;
}VNode,AdjList[MVNum];
typedef struct{
AdjList vertices;
int vexnum,arcnum;
}ALGraph;
#define MAXQSIZE 100
typedef struct{
int *base;
int front;
int rear;
}SqQueue;
void CreateUDN(AMGraph &G);
int LocateVex(AMGraph G,char v);
void CreateUDG(ALGraph &G);
int LocateVex(ALGraph G,char v);
void DFS(ALGraph G,int v);
void BFS(AMGraph G,int v);
void InitQueue(SqQueue &s);
int GetFront(SqQueue s,int e);
int EnQueue(SqQueue &s,int e);
int DeQueue(SqQueue &s,int e);
void ShortestPath_DIJ(AMGraph G,int v0);
int main(){
AMGraph G1;
ALGraph G2;
int v;
CreateUDN(G1);
CreateUDG(G2);
cout<<"请输出要从第几个顶点开始深度优先遍历:";
cin>>v;
cout<<"用邻接表方式实现深度优先遍历(递归方式):";
DFS(G2,v);
cout<<"\n请输出要从第几个顶点开始广度优先遍历:";
cin>>v;
cout<<"用邻接矩阵方式实现广度优先遍历(队列方式):";
BFS(G1,v);
cout<<"\n请输出要从第几个顶点开始计算最短路径:";
cin>>v;
cout<<"用迪杰斯特拉算法计算第"<<v<<"个顶点到其他几个顶点的最短路径"<<endl;
ShortestPath_DIJ(G1,v);
return 0;
}
//邻接矩阵创建无向网
void CreateUDN(AMGraph &G){
cout<<"-----邻接矩阵创建无向图-----"<<endl;
cout<<"请输入顶点个数和边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"输入顶点数据:"<<endl;
for(int i=0;i<G.vexnum;i++){
cin>>G.vexs[i];
}
for(int i=0;i<G.vexnum;i++){
for(int j=0;j<G.vexnum;j++){
G.arcs[i][j]=MaxInt;
}
}
char v1,v2;
int w,i,j;
cout<<"输入一条边的2个顶点和权值:"<<endl;
for(int k=0;k<G.arcnum;k++){
cin>>v1>>v2>>w;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j]=w;
G.arcs[j][i]=G.arcs[i][j];
}
cout<<"创建成功"<<endl;
cout<<"创建的邻接矩阵为:"<<endl;
for(int i=0;i<G.vexnum;i++){
cout<<"[";
for(int j=0;j<G.vexnum;j++){
if(G.arcs[i][j]==32767)
cout<<"* ";
else
cout<<G.arcs[i][j]<<" ";
}
cout<<"]"<<endl;
}
}
int LocateVex(AMGraph G,char v){
for(int i=0;i<G.vexnum;i++){
if(v==G.vexs[i]){
return i;
}
}
}
//邻接表创建无向网
void CreateUDG(ALGraph &G){
cout<<"-----邻接表创建无向图-----"<<endl;
cout<<"请输入顶点个数和边数:"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"输入顶点数据:"<<endl;
for(int i=0;i<G.vexnum;i++){
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;
}
char v1,v2;
int i,j;
ArcNode *p1,*p2;
cout<<"输入一条边的2个顶点:"<<endl;
for(int k=0;k<G.arcnum;k++){
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p1=new ArcNode;
p1->adjvex=j;
p1->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p1;
p2=new ArcNode;
p2->adjvex=i;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p2;
}
cout<<"创建成功"<<endl;
cout<<"创建的邻接表为:"<<endl;
for(int i=0;i<G.vexnum;i++){
ArcNode *p=G.vertices[i].firstarc;
cout<<i<<"->";
while(p!=NULL){
cout<<p->adjvex<<"->";
p=p->nextarc;
}
cout<<endl;
}
}
int LocateVex(ALGraph G,char v){
for(int i=0;i<G.vexnum;i++){
if(v==G.vertices[i].data){
return i;
}
}
}
//用邻接表方式实现深度优先遍历(递归方式)
//初始化访问标志数组,0为未访问
int visited[MVNum] = {0};
void DFS(ALGraph G,int v)
{
ArcNode *p;
visited[v] = 1;
cout<<v<<" ";
p=G.vertices[v].firstarc;
int temp;
while(p!=NULL){
temp=p->adjvex;
if(visited[temp]==0){
DFS(G,temp);
}
p=p->nextarc;
}
}
//用邻接矩阵方式实现广度优先遍历(队列方式)
void BFS(AMGraph G,int v)
{
int visited[MVNum] = {0};
int e;
//开始的点标明访问过
visited[v]=1;
SqQueue q;
InitQueue(q);
cout<<EnQueue(q,v)<<" ";
//只要队列不空,就出队,出队之前检查这个点有没有连通别的点且那个点没被访问过
while(q.front!=q.rear)
{
e=DeQueue(q,e);
for(int i=0;i<G.vexnum;i++){
if(G.arcs[e][i]!=MaxInt && visited[i]==0)
{
cout<<EnQueue(q,i)<<" ";
visited[i]=1;
}
}
}
}
//初始化循环队列
void InitQueue(SqQueue &s){
s.base=new int[MAXQSIZE];
s.front=s.rear=0;
}
//取队头元素
int GetFront(SqQueue s,int e){
if(s.front!=s.rear){
e=s.base[s.front];
}else{
cout<<"循环队列为空,无队头元素"<<endl;
}
return e;
}
//入循环队列
int EnQueue(SqQueue &s,int e){
if(s.front==((s.rear+1)%MAXQSIZE)){
cout<<"";
}else{
s.base[s.rear]=e;
s.rear=(s.rear+1)%MAXQSIZE;
}
return e;
}
//出循环队列
int DeQueue(SqQueue &s,int e){
if(s.front==s.rear){
cout<<"";
}else{
e=s.base[s.front];
s.front=(s.front+1)%MAXQSIZE;
}
return e;
}
//Dijkstra算法实现最短路径
void ShortestPath_DIJ(AMGraph G,int v0){
int n=G.vexnum,min,v,D[n],Path[n];
bool S[n];
for(v=0;v<n;v++){
S[v]=false;
D[v]=G.arcs[v0][v];
if(D[v]<MaxInt){
Path[v]=v0;
}else{
Path[v]=-1;
}
}
S[v0]=true;
D[v0]=0;
for(int i=1;i<n;i++){
min=MaxInt;
for(int w=0;w<n;w++){
if(!S[w] && D[w]<min){
v=w;
min=D[w];
}
}
S[v]=true;
for(int w=0;w<n;w++){
if(!S[w] && (D[v]+G.arcs[v][w]<D[w])){
D[w]=D[v]+G.arcs[v][w];
Path[w]=v;
}
}
}
//输出v0到其他结点所需最短路径
for(int i=0;i<n;i++){
cout<<i<<":"<<D[i]<<endl;
}
}