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

一、数组 (Array) 实现

1. 基础数组

cpp 复制代码
#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)

cpp 复制代码
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. 单链表实现

cpp 复制代码
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. 双链表实现

cpp 复制代码
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. 二叉树实现

cpp 复制代码
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树(平衡二叉搜索树)

cpp 复制代码
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. 邻接矩阵表示法

cpp 复制代码
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. 邻接表表示法(更高效)

cpp 复制代码
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等),这些实现主要用于学习原理。

相关推荐
川石课堂软件测试5 分钟前
Mysql中触发器使用详详详详详解~
数据库·redis·功能测试·mysql·oracle·单元测试·自动化
郝学胜-神的一滴10 分钟前
Python数据模型:深入解析及其对Python生态的影响
开发语言·网络·python·程序人生·性能优化
一水鉴天16 分钟前
整体设计 定稿 之26 重构和改造现有程序结构 之2 (codebuddy)
开发语言·人工智能·重构·架构
程序员游老板25 分钟前
基于SpringBoot3_vue3_MybatisPlus_Mysql_Maven的社区养老系统/养老院管理系统
java·spring boot·mysql·毕业设计·软件工程·信息与通信·毕设
star _chen39 分钟前
C++ std::move()详解:从小白到高手
开发语言·c++
lzhdim44 分钟前
C#开发者必知的100个黑科技(前50)!从主构造函数到源生成器全面掌握
开发语言·科技·c#
福尔摩斯张44 分钟前
C++核心特性精讲:从C语言痛点出发,掌握现代C++编程精髓(超详细)
java·linux·c语言·数据结构·c++·驱动开发·算法
刺客xs1 小时前
Qt----事件简述
开发语言·qt
程序员-King.1 小时前
【Qt开源项目】— ModbusScope-进度规划
开发语言·qt
syt_10131 小时前
Object.defineProperty和Proxy实现拦截的区别
开发语言·前端·javascript