查看: 23|回复: 0

二叉树入门指南:从零开始理解树形数据结构

[复制链接]
  • TA的每日心情

    昨天 14:37
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    15

    主题

    0

    回帖

    22

    积分

    新手上路

    Rank: 1

    积分
    22
    发表于 3 天前 | 显示全部楼层 |阅读模式
    一、简介和应用

    二叉树是一种重要的非线性数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。它在计算机科学中有广泛的应用,是许多高级数据结构的基础。

    ‌应用场景‌:

    • 1.数据库索引(如B树、B+树)
    • 2.文件系统目录结构
    • 3.表达式树(用于编译器实现)
    • 4.决策树(机器学习算法
    • 5.游戏AI中的决策系统
    • 6.哈夫曼编码(数据压缩)

    二叉树特别适合需要快速查找、插入和删除操作的场景,它的平均时间复杂度通常是O(log n)。

    二、实现步骤解析
    • 1‌.定义节点结构‌:创建包含数据、左指针和右指针的结构体
    • ‌2.初始化树‌:创建根节点作为树的起点
    • ‌3.实现基本操作‌:

      • 添加节点:指定父节点和位置添加新节点
      • 递归添加:自动找到合适位置添加节点
      • 删除节点:通过父节点移除指定子节点
      • 修改节点:直接修改指定节点的数据
      • 查找节点:递归搜索整个树

    • 4‌.实现遍历功能‌:

    三、完整代码和注释
    1. #include<iostream>
    2. using namespACe std;

    3. // 定义二叉树节点结构体
    4. struct treenode{
    5.     int data=0;            // 节点存储的数据,默认为0
    6.     treenode* left=nullptr;  // 左子节点指针,默认为空
    7.     treenode* right=nullptr; // 右子节点指针,默认为空
    8.    
    9.     // 默认构造函数
    10.     treenode() {}
    11.    
    12.     // 带参数的构造函数,可以指定父节点和位置
    13.     treenode(int d, treenode* h, bool children){
    14.         data = d;
    15.         if (!children)      // 如果是左子节点
    16.             h->left = this;  // 父节点的左指针指向当前节点
    17.         else                // 如果是右子节点
    18.             h->right = this; // 父节点的右指针指向当前节点
    19.     }
    20.    
    21.     // 只带数据的构造函数
    22.     treenode(int d){
    23.         data = d;
    24.     }
    25. };

    26. // 定义二叉树类
    27. class tree{
    28. public:
    29.     treenode* root; // 根节点指针
    30.    
    31.     // 构造函数,初始化根节点
    32.     tree(){
    33.         root = new treenode;
    34.     }
    35.    
    36.     // 在指定父节点的指定位置添加新节点
    37.     void add(treenode* parent, bool children, int data){
    38.         treenode* newnode = new treenode(data, parent, children);
    39.     }
    40.    
    41.     // 递归添加节点,自动找到合适位置
    42.     void add(treenode* node, int data){
    43.         if (!node->left){    // 如果左子节点为空
    44.             node->left = new treenode(data); // 添加到左子节点
    45.             return;
    46.         }
    47.         if (!node->right){   // 如果右子节点为空
    48.             node->right = new treenode(data); // 添加到右子节点
    49.             return;
    50.         }
    51.         add(node->left, data); // 递归尝试在左子树添加
    52.     }
    53.    
    54.     // 删除指定父节点的指定子节点
    55.     void remove(treenode* parent, bool children){
    56.         if (!children)       // 如果是左子节点
    57.             parent->left = nullptr;  // 置空左指针
    58.         else                 // 如果是右子节点
    59.             parent->right = nullptr; // 置空右指针
    60.         // 注意:这里应该释放被删除节点的内存
    61.     }
    62.    
    63.     // 修改指定节点的数据
    64.     void change(treenode* node, int data){
    65.         node->data = data;   // 直接修改数据
    66.     }
    67.    
    68.     // 递归查找包含指定数据的节点
    69.     treenode* find(int data, treenode* root){
    70.         if (!root)           // 如果当前节点为空
    71.             return nullptr;   // 返回空指针
    72.         if (root->data == data) // 如果找到数据
    73.             return root;      // 返回当前节点
    74.         treenode* ret;
    75.         ret = find(data, root->left);  // 在左子树中查找
    76.         if (ret)             // 如果在左子树中找到
    77.             return ret;      // 返回找到的节点
    78.         ret = find(data, root->right); // 在右子树中查找
    79.         if (ret)             // 如果在右子树中找到
    80.             return ret;      // 返回找到的节点
    81.         return nullptr;      // 没找到返回空指针
    82.     }
    83.    
    84.     // 前序遍历(根-左-右)
    85.     void printpre(treenode* node){
    86.         if (!node)           // 如果节点为空
    87.             return;          // 返回
    88.         cout << node->data << " "; // 先访问根节点
    89.         printpre(node->left);      // 再遍历左子树
    90.         printpre(node->right);     // 最后遍历右子树
    91.     }
    92.    
    93.     // 中序遍历(左-根-右)
    94.     void printmid(treenode* node){
    95.         if (!node)           // 如果节点为空
    96.             return;          // 返回
    97.         printmid(node->left);      // 先遍历左子树
    98.         cout << node->data << " "; // 再访问根节点
    99.         printmid(node->right);     // 最后遍历右子树
    100.     }
    101.    
    102.     // 后序遍历(左-右-根)
    103.     void printpost(treenode* node){
    104.         if (!node)           // 如果节点为空
    105.             return;          // 返回
    106.         printpost(node->left);     // 先遍历左子树
    107.         printpost(node->right);    // 再遍历右子树
    108.         cout << node->data << " "; // 最后访问根节点
    109.     }
    110. };
    复制代码
    转自:二叉树入门指南:从零开始理解树形数据结构


    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    快速回复 返回顶部 返回列表