C++数据结构之链表树图的存储

2024-05-11 19:52

本文主要是介绍C++数据结构之链表树图的存储,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文主要介绍用数组存储,结构只做简单介绍

目录

文章目录

前言

结构体实现

1、链表的存储

2、树的存储

3、图的存储

数组实现 

1、链表实现

2、树和图的实现

总结


前言

在正常工程中,我们通常使用结构体或者类,来定义并使用如链表,树,图这样的数据结构,但在算法中由于过多的调用,是打计算量大时候,结构体定义通常会慢,所以本文主要介绍一下数组实现上述数据结构。


结构体实现

对于结构或者类实现,就不做过多介绍,相关知识,在C++语言基础,面向对象程序设计以及数据结构内容都有涉及。下述直接给出相关代码实现

1、链表的存储

struct Node {int data;Node* next;
};// 创建一个新节点
Node* createNode(int data) {Node* newNode = new Node();newNode->data = data;newNode->next = nullptr;return newNode;
}// 在链表尾部插入节点
void insertAtEnd(Node*& head, int data) {Node* newNode = createNode(data);if (head == nullptr) {head = newNode;return;}Node* temp = head;while (temp->next != nullptr) {temp = temp->next;}temp->next = newNode;
}

2、树的存储

struct TreeNode {int data;TreeNode* left;TreeNode* right;
};// 创建一个新节点
TreeNode* createNode(int data) {TreeNode* newNode = new TreeNode();newNode->data = data;newNode->left = nullptr;newNode->right = nullptr;return newNode;   
}// 二叉树的前序遍历(根-左-右)
void preorderTraversal(TreeNode* root) {if (root == nullptr)return;cout << root->data << " ";preorderTraversal(root->left);preorderTraversal(root->right);
}

3、图的存储

 

class Graph {
private:int numVertices; // 图中顶点的数量list<int>* adjLists; // 邻接表public:Graph(int vertices) { // 构造函数,初始化图numVertices = vertices;adjLists = new list<int>[vertices];}void addEdge(int src, int dest) { // 添加边adjLists[src].push_back(dest); // 无向图需同时添加反向边adjLists[dest].push_back(src);}void printGraph() { // 打印图的邻接表表示for (int i = 0; i < numVertices; ++i) {cout << "顶点 " << i << " 的邻居节点:";for (const auto& neighbor : adjLists[i]) {cout << neighbor << " ";}cout << endl;}}
};

数组实现 

1、链表实现

int head, e[N], ne[N], idx;
// head 表示头结点的下标
// e[i] 表示节点i的值
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点// 初始化
void init()
{head = -1;idx = 0;
}
// 在链表头插入一个数a
void insert(int a)
{e[idx] = a, ne[idx] = head, head = idx ++ ;
}
//先用e存在a的值,ne存下指向的地址,head记录idx地址,idx指向下一个存储地址//为什么head=-1,这样最后可以判断到-1截止
//刚开始idx指向0,读入一个,指向下一个
for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';遍历

 

具体遍历实现如上,从head开始访问,然后不停通过ne得到地址,直到等于-1为止

当让理解如何存储是一样的,首先要存储读入a的值,即存入e中,同时使ne指向head指向的地址,head指向,idx指向地址,idx指向下一地址。具体实现上就是单链表的头插法。

2、树和图的实现

const int N = 100;  // 最大顶点数
const int M = 200;  // 最大边数int head[N];  
int e[M], ne[M];
int idx;      // 当前已经用到了哪个点// 初始化
void init() {memset(head, -1, sizeof(head));idx = 0;
}// 添加一条从u到v的有向边
void insert(int u, int v) {e[idx] = v;ne[idx] = head[u];head[u] = idx++;
}

 首先边M = 2 * N保证数组不会溢出,其次需要head数组来存多个头结点,同时都需要初始化为-1

其实这个定义的就是邻接表,用邻接表的方式实现了一个有向图的存储,其中每个顶点的链表表示与其相连的边。如果给定的边是一棵无环有向树(也就是树),则可以使用该数据结构进行存储和操作。

所以上述代码对于树和图的通用,具体原理其实和单链表一样的,每一个都是单链表

无向图只需要俩条有向图就能实现


总结

本文主要介绍了一下数组实现单链表,树和图的存储数据结构

推荐学习博客 https://xxetb.xetslk.com/s/4GgGz6

这篇关于C++数据结构之链表树图的存储的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/980493

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

k8s搭建nfs共享存储实践

《k8s搭建nfs共享存储实践》本文介绍NFS服务端搭建与客户端配置,涵盖安装工具、目录设置及服务启动,随后讲解K8S中NFS动态存储部署,包括创建命名空间、ServiceAccount、RBAC权限... 目录1. NFS搭建1.1 部署NFS服务端1.1.1 下载nfs-utils和rpcbind1.1

Redis高性能Key-Value存储与缓存利器常见解决方案

《Redis高性能Key-Value存储与缓存利器常见解决方案》Redis是高性能内存Key-Value存储系统,支持丰富数据类型与持久化方案(RDB/AOF),本文给大家介绍Redis高性能Key-... 目录Redis:高性能Key-Value存储与缓存利器什么是Redis?为什么选择Redis?Red

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本