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

相关文章

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)