实验五 图的操作(数据结构实验C++编写)

1.实验目的

(1)掌握图的邻接矩阵和邻接表存储方式;
(2)掌握图的遍历算法;
(3)掌握图的实际应用——最短路径算法。

2.实验内容

(1)采用邻接矩阵/邻接表建立图;
(2)采用深度优先/广度优先搜索方式遍历图;
(3)编程实现Dijkstra最短路径算法。

3.实验步骤

  1. 编写代码,采用邻接表法建立有向图:
    (1)输入总边数、总点数;
    (2)依次输入点的信息存入顶点表,使每个表头结点的指针域初始化为NULL;
    (3)创建邻接表,依次输入每条边依附的两个顶点,以及边的权值,确定这两个定点的序号i和j后,将边结点分别插入v_i和v_j对应的两个边链表的头部。
  2. 编写代码,实现深度优先搜索方式遍历图:
    (1)从图中某个顶点v出发,访问v,并设置visited[v]的值为true;
    (2)依次检查v的所有邻接点w,如果visited[w]的值为false,再从w出发进行递归遍历,直到图中所有顶点都被访问过。
  3. 编程实现Dijkstra最短路径算法。
    (1)初始化最短路径数组D,将其赋值为最大值10000;
    (2)如果v0与vi之间有弧,则将他们的权值赋给D[i];
    (3)初始化数组S,将源点v0加到S中,即S[v0] = true;
    (4)选择下一条最短路径的终点vk,令S[k]=true;
    (5)根据条件更新从v0到其他顶点的最短路径的长度,若D[k]+p->info<D[p->adjvex],则令D[p->adjvex] = D[k]+p->info。

4.实验代码

#include <iostream>
#include <iomanip>

using namespace std;
#define MVNum 100
bool visited[100] = {false};
//有向图的邻接表存储表示 95
typedef int OtherInfo;
typedef char VerTexType;
//边结点
typedef struct ArcNode
{
    int adjvex;                 //该边指向的顶点的位置
    struct ArcNode *nextarc;    //指向下一条边的指针
    OtherInfo info;             //权值
}ArcNode;
//顶点信息
typedef struct VNode
{
    VerTexType data;            //顶点的值
    ArcNode *firstarc;          //指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];
//邻接表
typedef struct
{
    AdjList vertices;
    int vexnum,arcnum;          //图的顶点数,边数
}ALGraph;
//确定定点u在图中的位置
int LocateVex(ALGraph G,VerTexType u);
//创建有向图
void CreateDG(ALGraph &G);
//深度优先遍历
void DFS_AL(ALGraph G,int v);
//Dijkstra算法
void ShortestPath_DIJ(ALGraph G,int v0);


int main()
{
    int v0;
    VerTexType data;

    ALGraph G;
    CreateDG(G);
    cout << "请输入v0的值:" ;
    cin >> data;
    v0 = LocateVex(G,data);
    cout << "深度优先遍历后得到的顶点顺序为:";
    DFS_AL(G,v0);
    cout << endl;
    cout << "请输入v0的值:" ;
    cin >> data;
    v0 = LocateVex(G,data);
    ShortestPath_DIJ(G,v0);

    return 0;
}

int LocateVex(ALGraph G,VerTexType u)
{
    //若G中存在顶点u,则返回该顶点的位置,否则返回-1.
    for(int i=0;i<G.vexnum;++i)
        if(u == G.vertices[i].data)
            return i;
    return -1;
}
void CreateDG(ALGraph &G)
{
    VerTexType v1,v2;
    OtherInfo otherInfo;
    //VerTexType ch[8] = "abcdefg";
    //VerTexType ch1[12] = "aaabcceffgd";
    //VerTexType ch2[12] = "bcdeefggdbg";
    //OtherInfo oi[11] = {15,2,12,6,8,4,9,10,5,4,3};
    int j,k;
    cout << "请输入图的总边数,总点数:";
    cin >> G.arcnum >> G.vexnum;
    //G.arcnum = 11;
    //G.vexnum = 7;
    cout << "请输入顶点的值:";

    //表头结点
    for(int i=0;i<G.vexnum;++i)
    {
        //G.vertices[i].data = ch[i];
        cin >> G.vertices[i].data;
        G.vertices[i].firstarc = NULL;
    }
    cout << "请输入一条边依附的两个顶点以及边的权值:";

    //边结点
    for(int i=0;i<G.arcnum;++i)
    {
        cin >> v1 >> v2 >> otherInfo;
        //v1 = ch1[i];v2 = ch2[i];otherInfo = oi[i];
        j = LocateVex(G,v1);
        k = LocateVex(G,v2);
        ArcNode* p1 = new ArcNode;
        p1->adjvex = k;
        p1->info = otherInfo;
        p1->nextarc = G.vertices[j].firstarc;
        G.vertices[j].firstarc = p1;
    }
}

void DFS_AL(ALGraph G,int v)
{

    int w;
    cout << v << ":" << G.vertices[v].data << " ";
    visited[v] = true;
    ArcNode* p = G.vertices[v].firstarc;
    while(p != NULL)
    {
        w = p->adjvex;
        if(!visited[w])
            DFS_AL(G,w);
        p = p->nextarc;
    }

}
void ShortestPath_DIJ(ALGraph G,int v0)
{
    int n = G.vexnum,k;
    bool S[n] = {false};
    OtherInfo D[n],Min;
    int Path[n];

    ArcNode* p;
    //初始化最短路径的值
    for(int v=0;v<n;++v)
        D[v] = 10000;
    p = G.vertices[v0].firstarc;
    //将与v0相关联的边的权值赋给D[]
    while(p != NULL)
    {
        D[p->adjvex] = p->info;
        p = p->nextarc;
    }
    S[v0] = true;       //将v0加入终点集
    Path[0] = v0;       //记录最短路径
    D[v0] = 0;
    for(int v=1;v<n;++v)
    {
        Min = 10000;
        //寻找最小值
        for(int w=0;w<n;++w)
        {
            if(!S[w] && D[w]<Min)
            {
                k = w;
                Min = D[w];
            }
        }
        S[k] = true;
        Path[v] = k;
        p = G.vertices[k].firstarc;
        while(p != NULL)
        {
            if(!S[p->adjvex] && D[k]+p->info<D[p->adjvex])
                D[p->adjvex] = D[k]+p->info;
            p = p->nextarc;
        }
    }
    for(int i=1;i<n;i++)
    {
        cout << "终点集为:";
        for(int j=0;j<=i;j++)
            cout << G.vertices[Path[j]].data;
        cout << setw(15) << "最短路径值为:" << D[Path[i]] << endl;
    }
}



5.实验总结

(1)邻接矩阵法适合建立稠密图;邻接表法适合建立稀疏图。
(2)深度优先搜索遍历类似于树的先序遍历,借助于栈结构来实现递归;广度优先搜索遍历类似于树的层次遍历,借助于队列结构来实现。
(3)Dijkstra算法求最短路径求解过程是,按照路径长度递增的次序产生最短路径,时间复杂度是O(n^2)。

数据结构核心原理与算法应用

猜你喜欢

转载自blog.csdn.net/weixin_43790779/article/details/106721840