数据结构—统计有向图中每个顶点的出度和入度(以邻接矩阵和邻接表两种方式实现)

本文详细介绍并实现了基于邻接矩阵和邻接表的图论算法,包括求解有向图的入度、出度及出度为零的顶点数量。通过具体代码示例,展示了如何在C++环境下构建图结构,并进行相关属性的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、邻接矩阵实现

假设不带权有向图采用邻接矩阵 g 存储,设计实现以下功能的算法:

1) 求出图中每个顶点的入度。

2) 求出图中每个顶点的出度。

3) 求出图中出度为0 的顶点数。

 

#include <stdio.h>

#include <stdlib.h>

#include <iostream>

using namespace std;



#define INFINITY 65535

#define MAX_VERTEX_NUM 100

typedef char VertexType;



typedef struct {

    VertexType vexs[MAX_VERTEX_NUM];  //顶点数组

    int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];     //邻接矩阵

    int v, e;      //图顶点和边的数量

} MGraph;

int num=0;   全局变量负责统计出度为0的顶点个数

void CreateMGraph(MGraph &G)

{

    int i,j,k,w;

    printf("输入顶点数和边数:\n");

    scanf("%d%d",&G.v,&G.e);

    //for(i=0;i<G.v;i++)

        //scanf("%c",G.vexs[i]);

    for(i=0;i<G.v;i++)

        for(j=0;j<G.v;j++)

            G.arcs[i][j]=INFINITY;    //初始化邻接矩阵

    for(k=0;k<G.e;k++)

    {

        printf("输入边(i,j)上的下标i,j和权w\n");

        scanf("%d%d%d",&i,&j,&w);

        G.arcs[i][j]=w;

    }

}

void indu(MGraph G)

{

     int n=0;

     printf("入度:\n");

     for(int i=0;i<G.v;i++)

     {

         for(int j=0;j<G.v;j++)

         {

             if(G.arcs[j][i]!=INFINITY)

                n++;

         }

         printf("%d ",n);

         n=0;

     }

}

void outdu(MGraph G)    //要不要加引用,有时候需要仔细考虑一下

{

     int n=0;

     printf("出度:\n");

     for(int i=0;i<G.v;i++)

     {

         for(int j=0;j<G.v;j++)

         {

             if(G.arcs[i][j]!=INFINITY)

                n++;

         }

         if(n==0)

            num++;

         printf("%d ",n);

         n=0;

     }

}

int main()

{

    MGraph G;

    CreateMGraph(G);

    indu(G);

    printf("\n");

    outdu(G);

    printf("\n");

    printf("出度为0的顶点个数:%d",num);

    return 0;

}

二、邻接表

假设不带权有向图采用邻接表 G 存储,设计实现以下功能的算法:

(1)求出图中每个顶点的入度。

(2)求出图中每个顶点的出度。

(3)求出图中出度为0 的顶点数。

#include <stdio.h>

#include <stdlib.h>

#include <iostream>

using namespace std;

#define INFINITY 65535

#define MAX_VERTEX_NUM 100

typedef int VertexType;

int num=0;

typedef struct ArcNode {

    int adjvex;     //邻接顶点的标号

    int weight;    //权重

    ArcNode *nextarc;

} ArcNode;   //边表

typedef struct {

    VertexType data; //VertexType可以写成结构体类型存储信息

    ArcNode *firstarc;

} VNode;   //顶点数组

typedef struct  {

    VNode adjlist[MAX_VERTEX_NUM];

    int v, e;

} ALGraph;

void CreateALGraph(ALGraph &G)   //创建邻接表

{

    int i,j,k;

    ArcNode *e;

    printf("输入顶点数和边数:\n");

    scanf("%d%d",&G.v,&G.e);

    for(i=0;i<G.v;i++)

    {

        //scanf("%d",&G.adjlist[i].data);

        G.adjlist[i].firstarc=NULL;

    }

    for(k=0;k<G.e;k++)

    {

        printf("输入边(vi,vj)上的顶点序号:\n");

        scanf("%d%d",&i,&j);

        e=(ArcNode*)malloc(sizeof(ArcNode));

        e->adjvex=j;

        e->nextarc=G.adjlist[i].firstarc;

        G.adjlist[i].firstarc=e;

        /*e=(ArcNode*)malloc(sizeof(ArcNode));

        e->adjvex=i;

        e->nextarc=G.adjlist[j].firstarc;

        G.adjlist[j].firstarc=e;*/

    }

}

void indu(ALGraph G)

{

    int i,j,n=0;

    int A[G.v];

    for(i=0;i<G.v;i++)

        A[i]=0;

    ArcNode *e;

        for(j=0;j<G.v;j++)

        {

        while(G.adjlist[j].firstarc!=NULL)

        {

            A[G.adjlist[j].firstarc->adjvex]++;

            e=G.adjlist[j].firstarc->nextarc;

            G.adjlist[j].firstarc=e;

        }

        }

        for(i=0;i<G.v;i++)

            printf("%d ",A[i]);

}

void outdu(ALGraph G)

{

    int n=0,i=0;

    ArcNode *e;

    for(i=0;i<G.v;i++)

    {

        while(G.adjlist[i].firstarc!=NULL)

        {

            n++;

            e=G.adjlist[i].firstarc->nextarc;

            G.adjlist[i].firstarc=e;

        }

        if(n==0)

            num++;

        printf("%d ",n);

        n=0;

    }

}

int main()

{

    ALGraph G;

    CreateALGraph(G);

    printf("出度:");

    outdu(G);

    printf("\n");

    printf("入度:");

    indu(G);

    printf("\n");

    printf("出度为0的节点数\n");

    printf("%d\n",num);

    return 0;

}

 

在C++中,我们可以使用邻接矩阵邻接表两种数据结构存储有向图,并计算每个顶点出度。以下是这两种情况下的简单示例: 1. **邻接矩阵**: 邻接矩阵是一个二维数组,其中行代表起点,列代表终点,元素值表示边的存在否或边的数量。假设我们有一个`bool adjMatrix[numVertices][numVertices]`矩阵。 ```cpp // 出度初始化为0 vector<int> outDegree(numVertices, 0); vector<int> inDegree(numVertices, 0); // 对于每条边 (u, v),在邻接矩阵中更新出度 for(int i = 0; i < numVertices; ++i) { for(int j = 0; j < numVertices; ++j) { if(adjMatrix[i][j]) { outDegree[j]++; // 如果是无向图,还需检查从v到u的边 if(!adjMatrix[j][i]) inDegree[i]++; } } } // 访问打印各顶点 for(int i = 0; i < numVertices; ++i) { cout << "Vertex " << i << ": Outdegree = " << outDegree[i] << ", Indegree = " << inDegree[i] << endl; } ``` 2. **邻接表**: 邻接表通常使用一个vector存储每个顶点的邻居列表,以及两个额外的vector,一个用于记录出度,一个用于记录。 ```cpp struct Node { int destination; int weight; // 可选,如果需要考虑权重 Node* next; }; // 同样,先初始化outDegreeinDegree为0 unordered_map<int, int> outDegreeMap; unordered_map<int, int> inDegreeMap; // 使用邻接表遍历并更新 for(Node* node : adjacencyList) { outDegreeMap[node->destination]++; if(node->source != -1) // 如果是无向图,则同时增加源节点的 inDegreeMap[node->source]++; } // 输出各顶点 for(auto it = outDegreeMap.begin(); it != outDegreeMap.end(); ++it) { cout << "Vertex " << it->first << ": Outdegree = " << it->second << ", Indegree = " << inDegreeMap[it->first] << endl; } ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值