邻接表求有向图各顶点的入度和出度 (图论基础)

有向图的邻接表用一个结构体LGraph存储表示,其中包括3个成员:顶点数组vertexs,顶点数vexnum和边数arcnum,其中顶点数组vertexs中每个元素都是VNode结构体变量。VNode结构体变量次年初图中每个顶点,它包含3个成员:顶点信息,出边表的表头指针和入边表的表头指针,其中后面两个成员都是ArcNode结构体类型的指针。ArcNode结构体存储边链表中的边节点,它包含两个成员:变的另一个邻接点的序号,以及指向下一个边节点的指针。

#define MAXN 100

struct ArcNode     //边节点;
{
    int adjvex;    //有向边的另一个邻接点的序号;
    ArcNode *nextarc;  //指向下一个边节点的指针;
};

struct VNode       //顶点;
{
    int data;      //顶点信息;
    ArcNode *head1;  //出边表的表头指针;
    ArcNode *head2;  //入边表的表头指针;
};

struct LGraph      //图的邻接表存储结构;
{
    VNode vertexs[MAXN];   //顶点数组;
    int vexnum, arcnum;    //顶点数,边(弧)数;
};

LGraph lg;  //图(邻接表存储结构)

出度入度邻接表存储结构形式代码实现如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 100
#define INF 0xFFFFFFF
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

struct ArcNode     //边节点;
{
    int adjvex;    //有向边的另一个邻接点的序号;
    ArcNode *nextarc;  //指向下一个边节点的指针;
};

struct VNode       //顶点;
{
    int data;      //顶点信息;
    ArcNode *head1;  //出边表的表头指针;
    ArcNode *head2;  //入边表的表头指针;
};

struct LGraph      //图的邻接表存储结构;
{
    VNode vertexs[MAXN];   //顶点数组;
    int vexnum, arcnum;    //顶点数,边(弧)数;
};

LGraph lg;  //图(邻接表存储结构)

void CreateLG()     //构造有向图G;
{
    ArcNode *pi;
    int v1, v2;
    for(int i=0; i<lg.vexnum; i++) {  //初始化表头指针为空;
        lg.vertexs[i].head1 = lg.vertexs[i].head2 = NULL;
    }
    for(int i=0; i<lg.arcnum; i++) {
        scanf("%d %d", &v1, &v2);
        v1--, v2--;
        pi = new ArcNode;     //添加出边;
        pi->adjvex = v2;
        pi->nextarc = lg.vertexs[v1].head1;
        lg.vertexs[v1].head1 = pi;
        pi = new ArcNode;     //添加入边;
        pi->adjvex = v1;
        pi->nextarc = lg.vertexs[v2].head2;
        lg.vertexs[v2].head2 = pi;
    }
}

//释放图G邻接表各顶点的边链表中的所有边节点所占的内存空间;
void Delete()
{
    ArcNode *pi;
    for(int i=0; i<lg.vexnum; i++) {
        pi = lg.vertexs[i].head1;
        while(pi != NULL) {
            lg.vertexs[i].head1 = pi->nextarc;
            delete pi;
            pi = lg.vertexs[i].head1;
        }
        pi = lg.vertexs[i].head2;
        while(pi != NULL) {
            lg.vertexs[i].head2 = pi->nextarc;
            delete pi;
            pi = lg.vertexs[i].head2;
        }
    }
}

int main(int argc, char *argv[])
{
    ArcNode *pi;
    int in_num, out_num;
    while(~scanf("%d %d", &lg.vexnum, &lg.arcnum)) {
        if(lg.vexnum == 0) break;
        CreateLG();

        /****输出每条边的出度****/
        for(int i=0; i<lg.vexnum; i++) {
            out_num = 0;
            pi = lg.vertexs[i].head1;
            while(pi != NULL) {
                out_num++;
                pi = pi->nextarc;
            }
            printf("%d", out_num);
            i == lg.vexnum-1 ? printf("\n") : printf(" ");
        }

        /****输出每条边的入度****/
        for(int i=0; i<lg.vexnum; i++) {
            in_num = 0;
            pi = lg.vertexs[i].head2;
            while(pi != NULL) {
                in_num++;
                pi = pi->nextarc;
            }
            printf("%d", in_num);
            i == lg.vexnum-1 ? printf("\n") : printf(" ");
         }
         Delete();
    }
    return 0;
}


在C++中,使用邻接表(Adjacency List)存储有向图是一种常见的数据结构选择,因为它对于稀疏图(边的数量远小于顶点数量的平方)来说非常高效,因为每个顶点只需要存储与其相邻的顶点列表,而不是所有可能的连接。 要计算有向图中某个顶点(in-degree)出度(out-degree),你可以创建两个哈希表或集合(如`std::unordered_map`),分别用于存储从其他顶点指向当前顶点的边(从当前顶点指向其他顶点的边(出度)。 以下是一个简单的例: ```cpp #include <iostream> #include <unordered_map> // 定义图节点类 class GraphNode { public: int vertex; std::unordered_map<int, bool> outgoing_edges; // 出度,键为邻接顶点,值为是否有边 GraphNode(int v) : vertex(v) {} }; // 计算出度 void compute_degrees(const std::vector<GraphNode>& graph, int node_id, int& in_degree, int& out_degree) { in_degree = 0; out_degree = graph[node_id].outgoing_edges.size(); for (const auto& edge : graph[node_id].outgoing_edges) { if (edge.second) { // 如果有边 in_degree++; } } } int main() { // 创建一个有向图邻接表,这里只是一个简化的例子,实际应用中会根据需添加更多节点 std::vector<GraphNode> graph = { {0, {{1, true}, {2, false}}}, // 0 -> 1, 0 -> 2 {1, {{0, true}, {3, true}}}, // 1 -> 0, 1 -> 3 {2, {{0, false}}}, // 2 -> 0 {3, {{1, true}}} // 3 -> 1 }; int in_degree, out_degree; compute_degrees(graph, 1, in_degree, out_degree); std::cout << "Vertex 1's in-degree: " << in_degree << ", out-degree: " << out_degree << std::endl; return 0; } ``` 在这个例中,我们首先定义了一个`GraphNode`类,其中包含一个顶点ID一个出度哈希表。然后在`compute_degrees`函数中,我们遍历该节点的出边并更新相应的数。 运行这个程序后,你会看到节点1的出度
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值