邻接表,深度优先/广度优先搜索方式遍历图
#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