/* 邻接表、构造有向图 */
#include <cstdio>
#include <cstdlib>
const int maxv = 20;
bool visited[maxv];
/* ALGraph类(邻接表构造图类) */
class ALGraph
{
private:
typedef struct ArcNode//弧结点
{
int adjvex;
int weight;
struct ArcNode *next;
}ArcNode;
typedef struct VNode//顶点结点
{
int vertex;
ArcNode *firstarc;
}VNode;
typedef struct
{
VNode adjlist[maxv];
int n,e;
}AdjList;
AdjList *g;
public:
ALGraph()//构造函数内,初始化成员AdjList *g
{
g = (AdjList*)malloc(sizeof(AdjList));
}
/* 构建图(邻接表)*/
void create_ALGraph()
{
ArcNode *p;
int i,j,w;
printf("输入顶点数,边数(n e): ");
scanf("%d%d",&g->n,&g->e);
for(int i = 0; i < g->n; i++)
{
g->adjlist[i].vertex = i;
g->adjlist[i].firstarc = NULL;
}
printf("输入边及权(i j weight):\n");
for(int k = 0; k < g->e; k++)
{
scanf("%d%d%d",&i,&j,&w);
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->weight = w;
p->next = g->adjlist[i].firstarc;
g->adjlist[i].firstarc = p;
}
}
/* 打印图(邻接表) */
void print_ALGraph()
{
ArcNode *p;
for(int i = 0; i < g->n; i++)
{
p = g->adjlist[i].firstarc;
printf("V%d",i);
while(p != NULL)
{
printf(" ->V%d(权:%d)",p->adjvex,p->weight);
p = p->next;
}
printf("\n");
}
}
/* 深度优先遍历(递归)*/
void dfs(int v)
{
ArcNode *p;
printf("V%d ",v);
visited[v] = 1;
p = g->adjlist[v].firstarc;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
dfs(p->adjvex);
p = p->next;
}
}
/* 广度优先遍历(队列)*/
void bfs(int v)
{
ArcNode *p;
int qu[maxv],front,rear;
front = rear = 0;
printf("V%d ",v);
visited[v] = 1;
rear = (rear+1) % maxv;
qu[rear] = v;
int w;
while(front != rear)
{
front = (front+1) % maxv;
w = qu[front];
p = g->adjlist[w].firstarc;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
{
printf("V%d ",p->adjvex);
visited[p->adjvex] = 1;
rear = (rear+1) % maxv;
qu[rear] = p->adjvex;
}
p = p->next;
}
}
printf("\n");
}
/* 判断两顶点是否连通 */
void ExistPath(int u,int v,bool &has)
{
ArcNode *p;
visited[u] = 1;
if(u == v)
{
has = true;
return ;
}
p = g->adjlist[u].firstarc;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
ExistPath(p->adjvex,v,has);
p = p->next;
}
}
/* 找到两点间路径,并输出所有路径 */
void FindPath(int u,int v,int path[],int d)
{
ArcNode *p;
d++; path[d] = u;
visited[u] = 1;
if(u == v && d >= 1)
{
for(int i = 0; i <= d; i++)
printf("V%d->",path[i]);
printf("\n");
}
p = g->adjlist[u].firstarc;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
FindPath(p->adjvex,v,path,d);
p = p->next;
}
visited[u] = 0;
}
/* g->n为ALGraph类私有成员
只能通过函数访问,获得图的边数n */
int ALGraph_n()
{
return g->n;
}
};
int main()
{
ALGraph algraph;//ALGraph类,实例化对象algraph
//freopen("data2.txt","r",stdin);
printf("create ALGraph(邻接表类)\n");
algraph.create_ALGraph();
printf("print ALGraph(邻接表类)\n");
algraph.print_ALGraph();
printf("-----------------\n");
/* 深度遍历操作 */
for(int i = 0; i < algraph.ALGraph_n(); i++)
visited[i] = 0;
printf("dfs: ");
algraph.dfs(0);
printf("\n");
/* 广度遍历操作 */
for(int i = 0; i < algraph.ALGraph_n(); i++)
visited[i] = 0;
printf("bfs: ");
algraph.bfs(0);
printf("\n");
printf("-----------------\n");
/* 两点间判定,是否连通 */
printf("输入两个顶点,判断是否连通(如: u v): ");
for(int i = 0; i < algraph.ALGraph_n(); i++)
visited[i] = 0;
bool has = false;
int u,v;
scanf("%d%d",&u,&v);
algraph.ExistPath(u,v,has);
int path[maxv];
int d = -1;
/* 若两点连通,输出所有路径 */
if(has == true)
{
printf("V%d、V%d连通,输出两点间所有路径:\n",u,v);
for(int i = 0; i < algraph.ALGraph_n(); i++)
{
visited[i] = 0;
path[i] = 0;
}
algraph.FindPath(u,v,path,d);
}
printf("\n");
system("Pause");
return 0;
}
/*
测试用例:
//(第一组)
4 4
0 1 9
1 2 8
0 2 7
3 2 6
0 2
//(第二组)
5 7
0 1 9
1 2 8
2 3 7
3 4 6
0 2 5
0 3 4
0 4 3
0 4
*/
邻接表、构造有向图
最新推荐文章于 2024-08-15 22:24:55 发布