【透过 C++ 实现数据结构:链表、数组、树和图蕴含的逻辑深度解析】

一、数组 (Array) 实现

1. 基础数组

#include <iostream>
using namespace std;

int main() {
    // 静态数组
    int staticArr[5] = {1,2,3,4,5};
    
    // 动态数组
    int size = 5;
    int* dynamicArr = new int[size];
    
    // 访问元素
    cout << "Third element: " << dynamicArr[2] << endl;
    
    delete[] dynamicArr; // 释放内存
    return 0;
}

2. 动态扩容数组(类似vector)

class DynamicArray {
private:
    int* arr;
    int capacity;
    int length;
    
public:
    DynamicArray() : capacity(2), length(0) {
        arr = new int[capacity];
    }

    void push_back(int val) {
        if(length == capacity) {
            // 扩容策略
            capacity *= 2;
            int* newArr = new int[capacity];
            for(int i=0; i<length; i++) {
                newArr[i] = arr[i];
            }
            delete[] arr;
            arr = newArr;
        }
        arr[length++] = val;
    }

    int at(int index) {
        if(index >= length) throw out_of_range("Index out of range");
        return arr[index];
    }

    ~DynamicArray() {
        delete[] arr;
    }
};

二、链表 (Linked List)

1. 单链表实现

class ListNode {
public:
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class LinkedList {
private:
    ListNode* head;
public:
    LinkedList() : head(nullptr) {}

    // 添加节点到头部
    void addFront(int val) {
        ListNode* newNode = new ListNode(val);
        newNode->next = head;
        head = newNode;
    }

    // 删除节点
    void deleteNode(int val) {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        
        while(curr) {
            if(curr->val == val) {
                if(prev) {
                    prev->next = curr->next;
                } else {
                    head = curr->next;
                }
                delete curr;
                return;
            }
            prev = curr;
            curr = curr->next;
        }
    }

    // 遍历打印
    void print() {
        ListNode* curr = head;
        while(curr) {
            cout << curr->val << " -> ";
            curr = curr->next;
        }
        cout << "null" << endl;
    }
};

2. 双链表实现

class DListNode {
public:
    int val;
    DListNode *prev, *next;
    DListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
};

class DoublyLinkedList {
private:
    DListNode* head;
    DListNode* tail;
public:
    // 添加节点到尾部
    void addBack(int val) {
        DListNode* newNode = new DListNode(val);
        if(!head) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            newNode->prev = tail;
            tail = newNode;
        }
    }
    
    // 其他操作类似单链表,需要处理prev指针
};

三、树 (Tree)

1. 二叉树实现

class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class BinaryTree {
private:
    TreeNode* root;

    // 递归插入
    TreeNode* insert(TreeNode* node, int val) {
        if(!node) return new TreeNode(val);
        
        if(val < node->val) {
            node->left = insert(node->left, val);
        } else {
            node->right = insert(node->right, val);
        }
        return node;
    }

public:
    BinaryTree() : root(nullptr) {}

    void insert(int val) {
        root = insert(root, val);
    }

    // 前序遍历
    void preOrder(TreeNode* node) {
        if(node) {
            cout << node->val << " ";
            preOrder(node->left);
            preOrder(node->right);
        }
    }
    
    // 其他遍历方式类似
};

2. AVL树(平衡二叉搜索树)

class AVLNode {
public:
    int val;
    AVLNode *left, *right;
    int height;
    AVLNode(int x) : val(x), left(nullptr), right(nullptr), height(1) {}
};

class AVLTree {
private:
    AVLNode* root;
    
    int getHeight(AVLNode* node) {
        return node ? node->height : 0;
    }
    
    // 右旋转
    AVLNode* rightRotate(AVLNode* y) {
        AVLNode* x = y->left;
        AVLNode* T2 = x->right;

        x->right = y;
        y->left = T2;

        y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
        x->height = max(getHeight(x->left), getHeight(x->right)) + 1;

        return x;
    }
    
    // 其他旋转操作和平衡因子计算...
};

四、图 (Graph)

1. 邻接矩阵表示法

class GraphMatrix {
private:
    int V; // 顶点数
    vector<vector<int>> adj;

public:
    GraphMatrix(int vertices) : V(vertices) {
        adj = vector<vector<int>>(V, vector<int>(V, 0));
    }

    void addEdge(int u, int v) {
        adj[u][v] = 1;
        adj[v][u] = 1; // 无向图
    }
};

2. 邻接表表示法(更高效)

class GraphList {
private:
    int V;
    vector<list<int>> adj;

public:
    GraphList(int vertices) : V(vertices), adj(vertices) {}

    void addEdge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u); // 无向图
    }

    // BFS遍历
    void BFS(int start) {
        vector<bool> visited(V, false);
        queue<int> q;
        
        visited[start] = true;
        q.push(start);

        while(!q.empty()) {
            int u = q.front();
            q.pop();
            cout << u << " ";

            for(int v : adj[u]) {
                if(!visited[v]) {
                    visited[v] = true;
                    q.push(v);
                }
            }
        }
    }
};

关键点解析:

  1. 内存管理

    • 使用new/delete管理堆内存
    • 链表节点要及时释放内存
    • 推荐使用智能指针(如unique_ptr
  2. 时间复杂度

    • 数组随机访问:O(1)
    • 链表插入/删除:O(1)(已知位置)
    • 二叉树平衡操作:O(log n)
  3. 设计模式

    • 使用类封装数据结构
    • 分离节点类和容器类
    • 实现迭代器模式遍历元素
  4. 扩展功能

    • 实现STL风格的接口(begin/end)
    • 添加异常处理
    • 支持模板泛型编程

建议按照以下顺序练习:

  1. 先实现数组和链表
  2. 再实现二叉树及其遍历
  3. 最后实现图结构及算法(DFS/BFS)
  4. 尝试实现更复杂的结构(红黑树、哈希表)

注意:实际开发中应优先使用STL容器(vector、list、map等),这些实现主要用于学习原理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP post 数据丢失问题

max_input_vars是PHP配置选项之一&#xff0c;用于设置一个请求中允许的最大输入变量数。它指定了在处理POST请求或者通过URL传递的参数时&#xff0c;PHP脚本能够接收和处理的最大变量数量。 max_input_vars的默认值是1000&#xff0c;意味着一个请求中最多可以包含1000个输入…

Mac下Python版本管理,适用于pyenv不起作用的情况

前言 声明&#xff1a;之前也在网上看到过可以使用pyenv来管理python版本&#xff0c;但由于作者的python安装路径实在是繁杂不堪&#xff0c;因此安装完成pyenv体验下来没有任何用处&#xff0c;但偶然发现vscode似乎可以看到各个python版本&#xff0c;因此写下这篇博客记录…

什么是完全前向保密(PFS)?

在当今数字化时代&#xff0c;信息安全至关重要。而密码学中的完全前向保密&#xff08;Perfect Forward Secrecy&#xff0c;简称PFS&#xff09;技术&#xff0c;已经成为保障信息安全的关键一环。如果没有完全前向保密&#xff0c;一旦长期密钥被泄露&#xff0c;攻击者就可…

计算机毕业设计SpringBoot+Vue.jst在线文档管理系统(源码+LW文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Vulnhun靶机-kioptix level 4-sql注入万能密码拿到权限ssh连接利用mysql-udf漏洞提权

目录 一、环境搭建信息收集扫描ip扫描开放端口扫描版本服务信息指纹探测目录扫描 二、Web渗透sql注入 三、提权UDF提权修改权限 一、环境搭建 然后选择靶机所在文件夹 信息收集 本靶机ip和攻击机ip 攻击机&#xff1a;192.168.108.130 靶机&#xff1a;192.168.108.141 扫描…

【NLP 31、预训练模型的发展过程】

人的行为&#xff0c;究竟是人所带来的思维方式不同还是与机器一样&#xff0c;刻在脑海里的公式呢&#xff1f; 只是因为不同的人公式不同&#xff0c;所以人的行为才不同&#xff0c;可这又真的是人引以为傲的意识吗&#xff1f; 人脑只是相当于一个大型、驳杂的处理器&#…

K8S下redis哨兵集群使用secret隐藏configmap内明文密码方案详解

#作者&#xff1a;朱雷 文章目录 一、背景环境及方案说明1.1、环境说明1.2、方案一&#xff1a;使用配置文件设置密码1.3、方案二&#xff1a;使用args 的命令行传参设置密码 二、redis secret configmap deployment参考2.1 创建secret-redis.yaml参考2.2 修改configmap配置参…

网络空间安全(2)应用程序安全

前言 应用程序安全&#xff08;Application Security&#xff0c;简称AppSec&#xff09;是一个综合性的概念&#xff0c;它涵盖了应用程序从开发到部署&#xff0c;再到后续维护的整个过程中的安全措施。 一、定义与重要性 定义&#xff1a;应用程序安全是指识别和修复应用程序…

【OS安装与使用】part5-ubuntu22.04基于conda安装pytorch+tensorflow

文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 明确pytorch安装依赖2.2.2 conda创建虚拟环境2.2.3 安装pytorch2.2.4 验证pytorch安装2.2.5 安装Tensorflow2.2.6 验证Tensorflow安装 三、疑问四、总结 一、待解决问题 1.1 问题…

基于Python/Java的医院系统切换互联网医院深度编程对接探索

一、引言 1.1 研究背景与意义 在当今数字化时代,医疗行业的信息化进程不断加速,医院信息系统(Hospital Information System,HIS)作为医疗信息化的核心组成部分,对于提升医院管理效率、优化医疗服务质量起着至关重要的作用。随着互联网技术的飞速发展,互联网医院应运而…

从零开始的网站搭建(以照片/文本/视频信息通信网站为例)

本文面向已经有一些编程基础&#xff08;会至少一门编程语言&#xff0c;比如python&#xff09;&#xff0c;但是没有搭建过web应用的人群&#xff0c;会写得尽量细致。重点介绍流程和部署云端的步骤&#xff0c;具体javascript代码怎么写之类的&#xff0c;这里不会涉及。 搭…

Linux权限(一)

文章目录 基本指令sudo权限chmod修改目标属性修改角色 修改权限属性目录权限缺省权限 基本指令 sudo 1. sudo是对指令的短暂提权的 2. 比如安装软件&#xff0c;安装到系统中&#xff0c;需要管理员root权限&#xff0c;这些命令其实只安装了一份&#xff0c;普通用户和超级用…

CV -- 基于GPU版CUDA环境+Pycharm YOLOv8 目标检测

目录 下载 CUDA 下载 cuDNN 下载 anaconda 安装 PyTorch pycharm 搭配 yolo 环境并运行 阅读本文须知&#xff0c;需要电脑中有 Nvidia 显卡 下载 CUDA 打开 cmd &#xff0c;输入 nvidia-smi &#xff0c;查看电脑支持 CUDA 版本&#xff1a; 我这里是12.0&#xff0c;进入…

R语言安装教程(附安装包)R语言4.3.2版本安装教程

文章目录 前言一、安装包下载二、R-4.3.2安装步骤三、rtools43安装步骤四、RStudio安装步骤 前言 本教程将详细、全面地为你介绍在 Windows 系统下安装 R 语言 4.3.2 的具体步骤。无论你是初涉数据领域的新手&#xff0c;还是希望更新知识体系的专业人士&#xff0c;只要按照本…

springBoot统一响应1.0版本

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

【STM32】内存管理

【STM32】内存管理 文章目录 【STM32】内存管理1、内存管理简介疑问&#xff1a;为啥不用标准的 C 库自带的内存管理算法&#xff1f;2、分块式内存管理&#xff08;掌握&#xff09;分配方向分配原理释放原理分块内存管理 管理内存情况 3、内存管理使用&#xff08;掌握&#…

DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

认知重构 | 自我分化 | 苏格拉底式提问

注&#xff1a;本文为 “认知重构 | 自我分化” 相关文章合辑。 心理学上有一个词叫&#xff1a;认知重构&#xff08;改变 “非黑即白&#xff0c;一分为二” 的思维方式&#xff09; 原创 心理师威叔 心理自救 2024 年 10 月 26 日 19:08 广东 你有没有过这样的时候&#x…

YARN的工作机制及特性总结

YARN hadoop的资源管理调度平台&#xff08;集群&#xff09;——为用户程序提供运算资源的管理和调度 用户程序&#xff1a;如用户开发的一个MR程序 YARN有两类节点&#xff08;服务进程&#xff09;&#xff1a; 1. resourcemanager 主节点master ----只需要1个来工作 2. nod…

LLM2CLIP论文学习笔记:强大的语言模型解锁更丰富的视觉表征

1. 写在前面 今天分享的一篇论文《LLM2CLIP: P OWERFUL L ANGUAGE M ODEL U NLOCKS R ICHER V ISUAL R EPRESENTATION》&#xff0c; 2024年9月微软和同济大学的一篇paper&#xff0c; 是多模态领域的一篇工作&#xff0c;主要探索了如何将大模型融合到Clip模型里面来进一步提…