浅谈【数据结构】图-图的存储

news2024/11/17 19:35:10

目录

1、图的存储

2、邻接表

3、十字链表


谢谢帅气美丽且优秀的你看完我的文章还要点赞、收藏加关注

没错,说的就是你,不用再怀疑!!!

希望我的文章内容能对你有帮助,一起努力吧!!!


1、图的存储

  • 邻接矩阵:数组表示法
    • 优势:存储/设计比较简单
    • 劣势:浪费空间。遍历出度比较费时间
  • 邻接表:通过数组+链表的形式来存储顶点出度关系
    • 优势:节省空间,遍历出度关系比较快
    • 劣势:操作相对邻接矩阵来说比较繁琐

2、邻接表

构建图类型

上述方式可以但是不够简洁

***领接表代码示例***

#include <iostream>
#include <cstring>

// 关系类型
typedef struct relation
{
    int index; // 下标
    int weight; // 权值
    struct relation *next; // 下一个关系的顶点的下标指针
}Relation_t;

// 顶点类型
typedef struct 
{
    std::string data; // 顶点数据
    Relation_t *first; // 该顶点的关系集
}Vertex_t;


// 当前顶点数
int current_count = 0;

/*
    @brief  创建一个图:邻接表
    @param  count 该图的最大顶点数量 
    @return 成功返回创建好的图指针
*/
Vertex_t *creatGraph(int count)
{
    // 申请空间
    Vertex_t *graph = new Vertex_t[count];

    // 初始化
    memset(graph,0,sizeof(Vertex_t)*count);

    std::cout << "请输入顶点数据空格分开(“结束”输入):";
    // 接受顶点

    while(1)
    {
        std::string data = "结束";
        std::cin >> data;
        if(data == "结束")
            break;

        if(current_count == count)
            break;

        // 新增顶点位置
        graph[current_count].data  = data;
        graph[current_count].first = nullptr;

        current_count++;
    }

    // 增加关系
    while(1)
    {
        std::cout << "请输入顶点关系(结束 结束 -1):";

        // 出发顶点和终止顶点 权值
        std::string start;
        std::string end;
        int data;
        std::cin >> start >> end >> data;

        if(start=="结束"||end=="结束"||data == -1)
            break;

        // 存储关系
        // 获取start和end在图数组的什么位置
        int index_s = 0,index_e = 0;
        for(;index_s < current_count;index_s++)
            if(graph[index_s].data == start)
                break;
        for(;index_e < current_count;index_e++)
            if(graph[index_e].data == end)
                break;

        // 两个顶点的下标找到了
        if(index_s == current_count||index_e == current_count)
            continue;
        
        // 添加关系
        Relation_t *rt = new Relation_t;
        rt->index = index_e;
        rt->weight = data;
        rt->next = nullptr;

        // 当至少存在出度顶点的时候
        if(graph[index_s].first)
        {
            Relation_t *rt_ptr = graph[index_s].first;
            while(rt_ptr->next)
                rt_ptr = rt_ptr->next;
            
            // 存进关系链表
            rt_ptr->next = rt;
        }
        else{ // 一个出度结点都没有的时候
            graph[index_s].first = rt;
        }
    }

    return graph;
}

void printrelation(Vertex_t *graph)
{
    if(!graph)
        std::cout << "空图" << std::endl;
    
    for(int count_v = 0;count_v < current_count;count_v++)
    {
        std::cout << "顶点<"<< graph[count_v].data <<">:";
        
        Relation_t *rt_ptr = graph[count_v].first;
        while(rt_ptr)
        {
            std::cout<< "<"<< graph[count_v].data <<","<< 
            graph[rt_ptr->index].data <<">" 
            << "("<<rt_ptr->weight<<")";
        
            rt_ptr = rt_ptr->next;
        }
        std::cout << std::endl;
    }
}


int main()
{
    Vertex_t *graph = creatGraph(10);

    printrelation(graph);

    delete []graph;

    return 0;
}








逆邻接表:通过数组+链表的形式来存储顶点入度关系

3、十字链表

  • 十字链表:通过邻接表+逆邻接表形式实现,用来存储一个顶点的入度出度
    • 更方便的遍历一个顶点的入度和出度顶点

***十字链表示例代码***

#include <iostream>
#include <list>
#include <vector>

using std::list;
using std::vector;

template <typename _v_type_,typename _r_type_>
class OrthogonalList
{
    // 关系结构体
    typedef struct 
    {
        int      index; // 下标
        _r_type_ weight;// 权值
    }Relation_t;

    // 顶点结构体
    typedef struct 
    {
        _v_type_ data; // 顶点
        list<Relation_t> enter_r; // 入度集
        list<Relation_t> out_r;   // 出度集
    }Vertex_t;

    // 顶点集
    vector<Vertex_t> vertex;

    // 计算下标
    int getIndex(_v_type_ vertex_v)
    {
        for(int index = 0;index < vertex.size();index++)
        {
            if(vertex_v == vertex[index].data)
                return index;
        }
        return -1;
    }
public:
    OrthogonalList() // 构造函数
        : vertex(0)
    {}
    ~OrthogonalList() // 析构函数
    {}
    void addVertex(_v_type_ vertex_v) // 增加顶点
    {
        Vertex_t vt;
        vt.data = vertex_v;
        vertex.push_back(vt);
    }
    void addRelation(_v_type_ vertex_s,_v_type_ vertex_e,_r_type_ relation) // 增加弧
    {
        // 获取顶点下标
        int vt_start = getIndex(vertex_s);
        int vt_end   = getIndex(vertex_e);
        if(vt_start==-1||vt_end==-1)
            return;

        // 出度
        Relation_t rt_o;
        rt_o.index = vt_end;
        rt_o.weight = relation;
        vertex[vt_start].out_r.push_back(rt_o);

        // 入度
        Relation_t rt_e;
        rt_e.index = vt_start;
        rt_e.weight = relation;
        vertex[vt_end].enter_r.push_back(rt_e);
    }
    void print()
    {
        std::cout << "顶点关系集" << std::endl;
        for(auto v : vertex)
        {
            std::cout << v.data << ":" << std::endl;
            std::cout << "入弧集:"; 
            for(auto r : v.enter_r)
                std::cout << vertex[r.index].data << ":" << r.weight << "  ";
            std::cout << std::endl;
            std::cout << "出弧集:";
            for(auto r : v.out_r)
                std::cout << vertex[r.index].data << ":" << r.weight << "  ";
            std::cout << std::endl;
        }
    }
};

int main()
{
    OrthogonalList<std::string,int> graph;

    std::cout <<"请输入顶点:";
    while(1)
    {
        std::string vertex = "结束";
        std::cin >> vertex;
        if(vertex == "结束")
            break;
        graph.addVertex(vertex);
    }

    while(1)
    {
        std::cout <<"请输入关系:";
        std::string vertex_s = "结束";
        std::string vertex_e = "结束";
        int data = -1;
        std::cin >> vertex_s >> vertex_e >> data;
        if(vertex_s == "结束"||vertex_e == "结束"||data == -1)
            break;
        graph.addRelation(vertex_s,vertex_e,data);
    }

    graph.print();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2075913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

知识竞赛中情境答题环节竞赛规则有哪些设计方案

情境题通常会给出一个具体的情景或场景&#xff0c;然后要求选手在该情境下回答问题、提出建议、解决问题等。目的是考察选手在特定情境下的分析和解决问题能力。一般由评委进行打分。 1.情境题可以是视频题&#xff0c;也可以是表演题&#xff0c;由选手抽一个题&#xff0c;…

东南亚媒体发布:5种东南亚地区媒体发稿技巧

东南亚国家是一个具有丰富多彩的文化的特点和媒体环境中的地域。想要在这个地区取得成功营销推广产品和服务&#xff0c;掌握如何有效与东南亚地区媒体协作尤为重要。下面我们就详细介绍五种在东南亚媒体发稿技巧&#xff0c;可以帮助读者高效地吸引住目标群体。 1.掌握市场定位…

机械学习—零基础学习日志(如何理解概率论8)

随机变量的协方差与相关系数 来一道练习题&#xff1a; 要先求出&#xff0c;a的数值&#xff1a; 要求联合分布律&#xff1a; 再求期望&#xff1a; 计算相关数值&#xff1a; 最后得到结果&#xff1a; 《概率论与数理统计期末不挂科|考研零基础入门4小时完整版&#xff08…

DaxPay:一套开源支付网关系统【送源码】

项目介绍 DaxPay是一套开源支付网关系统&#xff0c;已经对接支付宝、微信支付、云闪付相关的接口。可以独立部署&#xff0c;提供接口供业务系统进行调用&#xff0c;不对原有系统产生影响 特色功能 封装各类支付通道的接口为统一的接口&#xff0c;方便业务系统进行调用&am…

yocto | 基于Linux的定制系统跑Qt app(第二集)bitbake工作流程

点击上方"蓝字"关注我们 01、bitbake简介 >>> bitbake是OpenEmbedded构建系统的引擎,通过解析一系列配置文件(主要为recipes,即bb/bbappend文件)来创建任务列表,并根据依赖关系依次执行。通过bitbake -c listtasks xxx(模块名或映像名)命令可以查看…

【工具】Windows 上安装 PostgreSQL(图文详情)

目录 0.背景 1.简介 2.安装步骤 1&#xff09;下载地址 2&#xff09;双击安装包进行下载【请以管理员身份打开并安装】 3&#xff09;安装步骤 4&#xff09;安装中 5&#xff09;安装完成 0.背景 最近在学习大数据规模处理的相关课程&#xff0c;需要安装这个数据库以…

公园的客流统计意义何在,有哪些积极作用

随着城市化进程的加快&#xff0c;人们越来越重视休闲娱乐和亲近自然的机会。公园作为市民休闲放松的重要场所&#xff0c;其管理和维护的质量直接影响着市民的生活质量和城市的形象。客流统计在公园管理中扮演着重要角色&#xff0c;不仅可以帮助公园管理者更好地理解游客的行…

Ant Design Vue修改表格样式

原效果&#xff1a; 修改背景色和字体&#xff0c;包括表头和表体&#xff0c;要分开设置&#xff1a; :deep .ant-table-thead>tr>th {background: rgba(255, 255, 255, 0);//去掉表头背景color: rgb(100, 181, 220);font-weight: bold;border: none;//去掉表头边框}:d…

分组汇总后再根据数量拼上不同文字

Excel某表格有2列。 AB1Apples32Apples03Bananas14Bananas65Cantaloupe06Kiwis27Kiwis28Kiwis1 要求&#xff1a;按第1列分组&#xff0c;如果组内第2列大于0则对当前行进行计数&#xff0c;否则不计数&#xff1b;计数结果等于1则附加Occurrence&#xff0c;否则附加 Occurr…

连发3篇JHM !东北林业大学严善春教授和姜礅教授研究团队在重金属污染生态学与森林昆虫学交叉研究领域取得一系列新进展!

本文首发于“生态学者”微信公众号&#xff01; 近日&#xff0c;东北林业大学森林生态系统可持续经营教育部重点实验室严善春教授和姜礅教授项目组在重金属污染生态学与森林昆虫学交叉研究领域取得新进展。相关结果以“Cd exposure confers β-cypermethrin tolerance in Lym…

World of Warcraft [RETAIL] [70][Freeblue] /console WorldTextScale 3

魔兽正式服&#xff0c;打怪伤害数字显示大小&#xff0c;调整命令/console WorldTextScale n&#xff08;n 1,2,3,4,5,.....&#xff09; /console WorldTextScale 1 /console WorldTextScale 2 /console WorldTextScale 3 /console WorldTextScale 4 /console WorldTextSca…

驱动 day1 --内核的编译

1 内核编译&#xff1a;Makefile (1)下载linux源码 解压:sudo tar -xvf (3)编译内容 条件编译&#xff1a; 在内核的Makefile中&#xff0c;你可以通过检查.config文件中定义的配置宏来决定是否编译某个模块或文件 obj-$(CONFIG_LED) xx1.o obj-$(CONFIG_XX2) xx2.o …

【计算机网络】名词解释--网络专有名词详解

在网络通信中&#xff0c;有许多专业术语和概念&#xff0c;它们共同构成了网络通信的基础。以下是一些常见的网络术语及其定义和相互之间的关系&#xff1a; 一、网络基础 1.1 电路交换&#xff1a;电路交换是一种在数据传输前建立专用通信路径的通信方式。在通信开始前&…

振动分析-21-从管道的刚性和柔性连接到设备的刚性和柔性支撑

刚性连接与柔性连接在管道连接方面的应用介绍。 1 管道的刚性连接 1.1 刚性连接的概念与特点 刚性连接指的是管道之间的连接点在受到外力时几乎不会发生位移或变形。刚性连接使管道各部分成为一个固定且坚固的整体,具有高强度和高稳定性,能够有效抵抗外力的作用。 刚性连…

WEB服务器-Nginx源码安装及相关配置

一、web服务概述 二、Nginx 概述 三、Nginx源码安装 直接下载压缩包到/home家目录进行操作 3.1 下载所需环境 dnf install gcc pcre-devel zlib-devel openssl-devel -y 源码安装需要提前准备标准的编译器&#xff0c;GCC的全称是&#xff08;GNU Compiler collection&#x…

HAProxy 概述及搭建群集

一、HAProxy概述 HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理&#xff0c;是免费、快速并且可靠的一种解决方案。HAProxy非常适用于并发大&#xff08;并发达1w以上&#xff09;web站点&#xff0c;这些站点通常又需要会话保持或七层处理。HAProxy的运行模…

Cobalt Strike 4.8 用户指南-第三节-数据管理

3.1、概述 Cobalt Strike 团队服务器是行动期间 Cobalt Strike 收集的所有信息的中间商。Cobalt Strike 解析来自Beaconpayload 的输出&#xff0c;提取目标、服务和凭据。 如果想导出Cobalt Strike的数据&#xff0c;通过Reporting-->Export Data进行导出。Cobalt Strike…

DataX(Doris同步数据到SelectDB)

背景 由于之前的doris数仓在本地的服务器&#xff0c;当数据量越来越大&#xff0c;服务器的性能达不到要求&#xff0c;查询数据经常超时&#xff0c;故需要把本地的doris数仓部署到云上&#xff0c;本文以阿里云为例&#xff0c;迁移工具使用的阿里开源的datax。 datax官方文…

SpringBoot集成kafka开发-消息消费的分区策略(消费者如何判断从哪个分区中消费消息的?)

这里写目录标题 1、kafak消息者消费消息的4种分区策略2、kafka默认的消费分区策略1-RangeAssignor&#xff08;均匀分配、默认分配策略&#xff09;2.1、代码验证RangeAssignor的消息分区策略2.1.1、消费者2.1.2、生产者2.1.3、kafak配置类2.1.4、对象实体类2.1.5、项目配置文件…

LD3600F断路器LD3600F模块

LD3600F断路器LD3600F模块 LD3600F断路器LD3600F模块 LD3600F断路器LD3600F模块 LD3600F断路器LD3600F模块引脚线 LD3600F断路器LD3600F模块说明书 LD3600F断路器LD3600F模块接线图 LD3600F断路器是指能够关合、承载和开断正常回路条件下的电流并能在规定的时间内关合、承…