数据结构图的操作邻接表创建,深度、广度遍历,Dijkstra最短路径算法

本文详细介绍了使用邻接表存储无向图,并通过深度优先搜索(DFS)和广度优先搜索(BFS)两种方式遍历图的具体实现。此外,还深入探讨了Dijkstra算法在求解图中两点间最短路径问题的应用,提供了完整的算法实现代码。
摘要由CSDN通过智能技术生成

邻接表,深度优先/广度优先搜索方式遍历图

#include<iostream>
#include<cstring>
#define MaxV 100                    //宏定义最大顶点数
using namespace std;
int visited[MaxV];                  //设置标记数组
typedef struct ArcNode
{
     int adjvex;              		//邻接点域,存储该邻点顶点对应的下标
     struct ArcNode *nextarc;		//邻节点
}ArcNode;
typedef struct VNode
{
     char data;	   			        //顶点对应的数据
     ArcNode  *firstarc;            //边表头指针指向邻顶点
}VNode,AdjList[MaxV];
typedef struct
{
     AdjList  vertices;             //MaxV个顶点结点
     int vexnum,arcnum;			    //顶点数,边数
}ALGraph;
typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
    int    data[MaxV];
    int    front,rear;
}Queue;                             //队列结构的定义
void CreateALGraph(ALGraph *G);     //无向图的创建
void DFS(ALGraph G,int i);          //深度优先搜索遍历
void InitQueue(Queue &Q);           //初始化队列
void EnQueue(Queue &Q,int e);       //入队
bool QueueEmpty(Queue &Q);          //判断队列是否为空
void DeQueue(Queue &Q,int &e);      //出队
void BFS(ALGraph &G);               //广度优先搜索遍历
void CreateALGraph(ALGraph *G)
{
    cout<<"请输入总顶点与总边的数目:"<<endl;;
    cin>>G->vexnum>>G->arcnum;
    cout<<"依次输入"<<G->vexnum<<"个顶点值:"<<endl;;
    for(int k=1;k<=G->vexnum;k++)
    {
        cin>>G->vertices[k].data;
        G->vertices[k].firstarc=NULL;
    }
    cout<<"依次输入"<<G->arcnum<<"条边起始点与结束点对应的下标:"<<endl;
    for(int k=1;k<=G->arcnum;k++)
    {
        int i,j;                    //i表示这条边起始点对应的下标
                                    //j表示这条边结束点对应的下标
        cin>>i>>j;
        ArcNode *p=new ArcNode;
        p->adjvex=j;
        p->nextarc=G->vertices[i].firstarc;
        G->vertices[i].firstarc=p;
        ArcNode *q=new ArcNode;
        q->adjvex=i;
        q->nextarc=G->vertices[j].firstarc;
        G->vertices[j].firstarc=q;
    }
}
void DFS(ALGraph G,int i)
{
    visited[i]=1;                    //将要访问过的置为1
    cout<<G.vertices[i].data<<" ";   //输出顶点
    ArcNode *p=G.vertices[i].firstarc;
    while(p)
    {
        int j=p->adjvex;
        if(!visited[j])
            DFS(G,j);
        p=p->nextarc;
    }
}
void InitQueue(Queue &Q)
{
    Q.front=Q.rear=0;
}
void EnQueue(Queue &Q,int e)
{
    if ((Q.rear+1)%MaxV == Q.front)
        return;
    Q.data[Q.rear]=e;
    Q.rear=(Q.rear+1)%MaxV;
}
bool QueueEmpty(Queue &Q)
{
    if (Q.front==Q.rear)
        return true;
    else
        return false;
}
void DeQueue(Queue &Q,int &e)
{
    if (Q.front==Q.rear)
        return;
    e=Q.data[Q.front];
    Q.front=(Q.front+1)%MaxV;
}
void BFS(ALGraph &G)
{
    ArcNode *p;
   	Queue Q;
   	InitQueue(Q);
    for(int j = 1; j<=G.vexnum; j++)
    {
        if(!visited[j])
        {
            cout<<G.vertices[j].data<<" ";  //打印顶点
			 visited[j] = 1;
            EnQueue(Q,j);
            while(!QueueEmpty(Q))
            {
                int m;
                DeQueue(Q,m);      		 //访问点出队列
                p=G.vertices[m].firstarc;//找到当前顶点边表链表头指针
                while(p)
                {
                    if(!visited[p->adjvex])
                    {
                        cout<<G.vertices[p->adjvex].data<<" ";
                        visited[p->adjvex] = 1;
                        EnQueue(Q,p->adjvex);
                    }
                    p=p->nextarc;
                }
            }
        }
    }
}
int main()
{
    ALGraph G;                         //定义无向图G
    CreateALGraph(&G);                 //创建邻接表
    memset(visited,0,sizeof(visited)); //将标记数组置为0
    cout<<"深度优先搜索遍历:";
    DFS(G,1);                          //从第一个顶点进行深度优先遍历
    cout<<endl;
    memset(visited,0,sizeof(visited)); //将标记数组置为0
    cout<<"广度优先搜索遍历:";
    BFS(G);                            //广度优先搜索遍历
    return 0;
}

实现Dijkstra最短路径算法

#include <iostream>
#define INF 9999
using namespace std;
struct node
{
	int node,next;
	int weight;
}edge[10000];
int first_arc[300],cnt;
void addEdge(int x,int y,int w)
{
	edge[cnt].node=y;
	edge[cnt].next=first_arc[x];
	first_arc[x]=cnt;
	edge[cnt].weight=w;
	++cnt;
}
int main()
{
    cout<<"请输入测试数据:"<<endl;
	int n,m,u,v,w,start;
	cin>>n>>m>>start;
	for(int i=0;i<n;++i)
        first_arc[i]=-1;
	for(int i=0;i<m;++i)
	{
		cin>>u>>v>>w;
		addEdge(u,v,w);
	}
	int dist[100],s[100],path[100];
	for(int i=0;i<n;++i)
	{
		dist[i]=INF;
		s[i]=0;
		path[i]=-1;
	}
	int p=first_arc[start];
	while(p!=-1)
	{
		dist[edge[p].node]=edge[p].weight;
		path[edge[p].node]=start;
		p=edge[p].next;
	}
	s[start]=1;
	path[start]=0;
	int min_dist,k;
	for(int i=0;i<n;++i)
	{
	   	min_dist=INF;
	   	for(int j=0;j<n;++j)
	   	   if(s[j]==0&&dist[j]<min_dist)
	   	   {
	   	   	  k=j;
	   	   	  min_dist=dist[j];
	   	   }
	   	s[k]=1;
	   	p=first_arc[k];
	   	while(p!=-1)
		{
			int t=edge[p].node;
			if(s[t]==0&&dist[k]+edge[p].weight<dist[t])
			{
				dist[t]=dist[k]+edge[p].weight;
                path[t]=k;
			}
			p=edge[p].next;
		}
	}
	int output[100],out_cnt,t;
	for(int i=0;i<n;++i)
	   if(s[i]==1&&i!=start)
	   {
		    cout<<start<<" to "<<i<<" with length "<<dist[i]<<" :";
		   	out_cnt=0;
		   	output[out_cnt]=i;
		   	t=path[i];
		   	if(t==-1)
		   	   cout<<"no path"<<endl;
		   	else
		    {
		    	while(t!=start)
		    	{
		    		++out_cnt;
		    		output[out_cnt]=t;
		    		t=path[t];
		    	}
		    	++out_cnt;
		    	output[out_cnt]=start;
		    	cout<<output[out_cnt];
		    	for(int j=out_cnt-1;j>=0;--j)
		    	   cout<<','<<output[j];
		    	cout<<endl;
		    }
	   }
}

测试数据
7 12 0
0 1 4
0 3 6
0 2 6
1 4 7
1 2 1
3 2 2
3 5 5
2 4 6
2 5 4
4 6 6
5 4 1

5 6 8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值