图的操作(c++实现)

(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;
    }
}

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页