邻接表、构造有向图

/* 邻接表、构造有向图 */
#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
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值