栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【数据结构】图的操作算法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【数据结构】图的操作算法

【数据结构】图的操作算法
  • 实验内容
  • 设计思路
  • 实验代码


实验内容
  1. 编写一个程序,输出下面带权有向图的邻接表,并根据该邻接表,实现图的遍历运算,具体要求如下:
    (1)从顶点0开始的深度优先遍历序列(递归算法)
    (2)从顶点0开始的广度优先遍历序列

    具体效果如下:
  2. 采用狄克斯特拉算法(Dijkstra),输出下面有向带权图G中从顶点0到其它各顶点的最短路径和最短路径长度。

    具体效果如下:

设计思路
任务一
(一)在graph.h中创建图的邻接表存储结构:
1.首先定义邻接表类型中的边结点类型ArcNode;
2.然后定义邻接表头结点类型VNode;
3.接着定义完整的图邻接表类型AdjGraph。
(二)在graph.h中创建队列的存储结构:
1.首先定义队列SqQueue
2.完成队列的基本算法
初始化InitQueue(SqQueue *&q)
判断是否为空QueueEmpty(SqQueue *q)
进队列enQueue(SqQueue *&q,int e)
出队列deQueue(SqQueue *&q,int &e)
(三)在main.cpp中完成图的基本运算算法:
1. 创建图的邻接表CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e);
2. 输出邻接表G DispAdj(AdjGraph G);
3. 销毁图的邻接表DestroyAdj(AdjGraph *&G);
4. 定义全局函数visited[MAXV];
5. 递归深度优先算法DFS(AdjGraph *G,int v);
6. 非递归深度优先算法DFS1(AdjGraph *G,int v);
7. 非递归广度优先算法BFS(AdjGraph *G,int v);
8.主函数 main()根据问题依次调用基本操作函数并编写通俗易懂的语句输出。

任务二
(一)在Dijkstra.h中创建图的邻接表存储结构:
1.首先定义邻接表类型中的边结点类型ArcNode;
2.然后定义邻接表头结点类型VNode;
3.接着定义完整的图邻接表类型AdjGraph。
(二)在main.cpp中完成图的基本运算算法:
1. 创建图的邻接表CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e);
2.  Dijkstra算法Dijkstra(MatGraph g,int v);
3. 输出从顶点v出发的所有最短路径Dispath(MatGraph g,int dist[],int path[],int S[],int v)

实验代码
#include 
#include
#define MAXV 100
#define MaxSize 100
#define INF 327676
using namespace std;
typedef char InfoType;
typedef char ElemType;

//以下定义邻接表类型
typedef struct ANode
{
    int adjvex;					//该边的邻接点编号
    struct ANode *nextarc;		//指向下一条边的指针
    int weight;					//该边的相关信息,如权值(用整型表示)
} ArcNode;						//边结点类型
typedef struct Vnode
{
    InfoType info;				//顶点其他信息
    int count;					//存放顶点入度,仅仅用于拓扑排序
    ArcNode *firstarc;			//指向第一条边
} VNode;						//邻接表头结点类型
typedef struct
{
    VNode adjlist[MAXV];		//邻接表头结点数组
    int n,e;					//图中顶点数n和边数e
} AdjGraph;						//完整的图邻接表类型
//队列定义
typedef struct SqQueue
{
    ElemType data[MaxSize];
    int front,rear;
} SqQueue;
//初始化
void InitQueue(SqQueue *&q)
{
    q=(SqQueue *)malloc(sizeof(SqQueue));
    q->front=q->rear=-1;
}
//判断是否为空
bool QueueEmpty(SqQueue *q)
{
    return(q->front==q->rear);
}
//进队列
bool enQueue(SqQueue *&q,int e)
{
    if(q->rear==MaxSize-1)
        return false;
    q->rear++;
    q->data[q->rear]=e;
    return true;
}
//出队列
bool deQueue(SqQueue *&q,int &e)
{
    if(q->front==q->rear)
        return false;
    q->front++;
    e=q->data[q->front];
    return true;
}

//Main.cpp
#include 
#define MAXV 100
#define MaxSize 100
#define INF 327676
#include "graph.h"
//----创建图的邻接表G----------------------------------
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e) //创建图的邻接表
{
    int i,j;
    ArcNode *p;
    G=(AdjGraph *)malloc(sizeof(AdjGraph));
    for (i=0; iadjlist[i].firstarc=NULL;
    for (i=0; i=0; j--)
            if (A[i][j]!=0 && A[i][j]!=INF)			//存在一条边
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));	//创建一个结点p
                p->adjvex=j;
                p->weight=A[i][j];
                p->nextarc=G->adjlist[i].f
                           irstarc;	//采用头插法插入结点p
                G->adjlist[i].firstarc=p;
            }
    G->n=n;
    G->e=n;
}
//----输出邻接表G----------------------------------
void DispAdj(AdjGraph *G)
{
    int i;
    ArcNode *p;
    for (i=0; in; i++)
    {
        p=G->adjlist[i].firstarc;
        printf("%3d: ",i);
        while (p!=NULL)
        {
            printf("%3d(%d) ",p->adjvex,p->weight);
            p=p->nextarc;
        }
        printf("n");
    }
}
//----销毁图的邻接表----------------------------------
void DestroyAdj(AdjGraph *&G)
{
    int i;
    ArcNode *pre,*p;
    for (i=0; in; i++)			//扫描所有的单链表
    {
        pre=G->adjlist[i].firstarc;	//p指向第i个单链表的首结点
        if (pre!=NULL)
        {
            p=pre->nextarc;
            while (p!=NULL)			//释放第i个单链表的所有边结点
            {
                free(pre);
                pre=p;
                p=p->nextarc;
            }
            free(pre);
        }
    }
    free(G);						//释放头结点数组
}
//----深度优先递归算法----------------------------------
int visited[MAXV];						//全局数组
void DFS(AdjGraph *G,int v)   //递归深度优先算法
{
    ArcNode *p;
    visited[v]=1;                   	//置已访问标记
    printf("%3d",v); 					//输出被访问顶点的编号
    p=G->adjlist[v].firstarc;      		//p指向顶点v的第一条弧的弧头结点
    while (p!=NULL)
    {
        if (visited[p->adjvex]==0)		//若p->adjvex顶点未访问,递归访问它
            DFS(G,p->adjvex);
        p=p->nextarc;              		//p指向顶点v的下一条弧的弧头结点
    }
}
//----深度优先非递归算法----------------------------------
void DFS1(AdjGraph *G,int v)   //非递归深度优先算法
{
    ArcNode *p;
    ArcNode *St[MAXV];
    int top=-1,w,i;
    for (i=0; in; i++)
        visited[i]=0;		//顶点访问标志均置成0
    printf("%3d",v);        //访问顶点v
    visited[v]=1;
    top++;                  //将顶点v的第一个相邻顶点进栈
    St[top]=G->adjlist[v].firstarc;
    while (top>-1)          //栈不空循环
    {
        p=St[top];
        top--;   //出栈一个顶点作为当前顶点
        while (p!=NULL)     //查找当前顶点的第一个未访问的顶点
        {
            w=p->adjvex;
            if (visited[w]==0)
            {
                printf("%3d",w); //访问w
                visited[w]=1;
                top++;           //将顶点w的第一个顶点进栈
                St[top]=G->adjlist[w].firstarc;
                break;           //退出循环
            }
            p=p->nextarc;        //找下一个相邻顶点
        }
    }
}
//BFS非递归算法
void BFS(AdjGraph *G,int v)
{
    int w,i;
    ArcNode *p;
    SqQueue *qu;
    InitQueue(qu);
    int visited[MAXV];
    for(i=0; in; i++)
        visited[i]=0;
    printf("%3d",v);
    visited[v]=1;
    enQueue(qu,v);
    while(!QueueEmpty(qu))
    {
        deQueue(qu,w);
        p=G->adjlist[w].firstarc;
        while(p!=NULL)
        {
            if(visited[p->adjvex]==0)
            {
                printf("%3d",p->adjvex);
                visited[p->adjvex]=1;
                enQueue(qu,p->adjvex);
            }
            p=p->nextarc;
        }
    }
    printf("n");
}

int main()
{
    AdjGraph *G;
    int A[MAXV][MAXV]=
    {
        {0,5,INF,7,INF,INF},
        {INF,0,4,INF,INF,INF},
        {8,INF,0,INF,INF,9},
        {INF,INF,5,0,INF,6},
        {INF,INF,INF,5,0,INF},
        {3,INF,INF,INF,1,0}
    };
    int n=6, e=10;
    CreateAdj(G,A,n,e);             //建立实验讲义中的邻接表
    printf("图G的邻接表:n");
    DispAdj(G);                     //输出邻接表
    printf("从顶点0开始的DFS(递归算法):n");
    DFS(G,0);
    printf("n");
    printf("从顶点0开始的DFS(非递归算法):n");
    DFS1(G,0);
    printf("n");
    printf("从顶点0开始的BFS(非递归算法):n");
    BFS(G,0);

}

#include "Dijkstra.h"
int count=0;
void Dispath(MatGraph g,int dist[],int path[],int S[],int v)
//输出从顶点v出发的所有最短路径
{
    int i,j,k;
    int apath[MAXV],d;					//存放一条最短路径(逆向)及其顶点个数
    for (i=0; i
            printf("  从顶点%d到顶点%d的路径长度为:%dt路径为:",v,i,dist[i]);
            d=0;
            apath[d]=i;			//添加路径上的终点
            k=path[i];
            if (k==-1)					//没有路径的情况
                printf("无路径n");
            else						//存在路径时输出该路径
            {
                while (k!=v)
                {
                    d++;
                    apath[d]=k;
                    k=path[k];
                }
                d++;
                apath[d]=v;		//添加路径上的起点
                printf("%d",apath[d]);	//先输出起点
                for (j=d-1; j>=0; j--)	//再输出其他顶点
                    printf(",%d",apath[j]);
                printf("n");
            }
        }
}

void Dijkstra(MatGraph g,int v)	//Dijkstra算法
{
    int dist[MAXV],path[MAXV];
    int S[MAXV];				//S[i]=1表示顶点i在S中, S[i]=0表示顶点i在U中
    int Mindis,i,j,u;
    for (i=0; i
        dist[i]=g.edges[v][i];	//距离初始化
        S[i]=0;					//S[]置空
        if (g.edges[v][i]
        Mindis=INF;				//Mindis置最大长度初值
        for (j=0; j
                u=j;
                Mindis=dist[j];
            }

        S[u]=1;					//顶点u加入S中

        for (j=0; j
                if (g.edges[u][j]
                    dist[j]=dist[u]+g.edges[u][j];
                    path[j]=u;
                }
            }

    }
    Dispath(g,dist,path,S,v);	//输出最短路径
}

int main()
{
    MatGraph g;
    int A[MAXV][MAXV]=
    {
        {0,5,INF,7,INF,INF},
        {INF,0,4,INF,INF,INF},
        {8,INF,0,INF,INF,9},
        {INF,INF,5,0,INF,6},
        {INF,INF,INF,5,0,INF},
        {3,INF,INF,INF,1,0}
    };
    int n=6, e=8;
    CreateMat(g,A,n,e);			//建立图的邻接矩阵
    printf("图G的邻接矩阵:n");
    DispMat(g);					//输出邻接矩阵
    int v=0;
    printf("从%d顶点出发的最短路径求解过程如下:n",v);
    Dijkstra(g,v);
    return 1;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/975200.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号