• 【数据结构】树与二叉树(二):树的表示C语言:树形表示法、嵌套集合表示法、嵌套括号表示法 、凹入表示法


    5.1 树的基本概念

    5.1.1 树的定义

    • 一棵树是结点的有限集合T:
      • 若T非空,则:
        • 有一个特别标出的结点,称作该树的,记为root(T);
        • 其余结点分成若干个不相交的非空集合T1, T2, …, Tm (m>0),其中T1, T2, …, Tm又都是树,称作root(T)的子树
          • 在这里插入图片描述
      • T 空时为空树,记作root(T)=NULL。

    5.1.2 森林的定义

      一个森林是0棵或多棵不相交(非空)树的集合,通常是一个有序的集合。换句话说,森林由多个树组成,这些树之间没有交集,且可以按照一定的次序排列。在森林中,每棵树都是独立的,具有根节点和子树,树与树之间没有直接的连接关系。
      森林是树的扩展概念,它是由多个树组成的集合。在计算机科学中,森林也被广泛应用于数据结构和算法设计中,特别是在图论和网络分析等领域。
    在这里插入图片描述

    5.1.3 树的术语

    • 父亲(parent)、儿子(child)、兄弟(sibling)、后裔(descendant)、祖先(ancestor)
    • 度(degree)、叶子节点(leaf node)、分支节点(internal node)
    • 结点的层数
    • 路径、路径长度、结点的深度、树的深度

    参照前文:【数据结构】树与二叉树(一):树(森林)的基本概念:父亲、儿子、兄弟、后裔、祖先、度、叶子结点、分支结点、结点的层数、路径、路径长度、结点的深度、树的深度

    5.1.4 树的表示

    1.树形表示法

      树形表示法是一种图形化的表示方法,使用节点和边来表示树的结构。每个节点代表树中的一个元素,而边表示节点之间的关系。这种表示方法可以直观地展示树的层次结构和节点之间的连接关系。

    在这里插入图片描述

    2.嵌套集合表示法

      嵌套集合表示法使用集合的嵌套结构来表示树:每个集合代表一个节点,而集合中的元素表示该节点的子节点。通过嵌套的方式,可以表示出树的层次结构。

    tree = {
        'value': 'A',
        'children': [
            {
                'value': 'B',
                'children': []
            },
            {
                'value': 'C',
                'children': [
                    {
                        'value': 'D',
                        'children': []
                    }
                ]
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    结构体
    #include 
    #include 
    
    struct TreeNode {
        int value;
        struct TreeNode** children;
        int numChildren;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    创建树
    struct TreeNode* createTreeNode(int value, int numChildren) {
        struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        node->value = value;
        node->numChildren = numChildren;
        node->children = (struct TreeNode**)malloc(numChildren * sizeof(struct TreeNode*));
        for (int i = 0; i < numChildren; i++) {
            node->children[i] = NULL;
        }
        return node;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    主函数
    int main() {
        struct TreeNode* root = createTreeNode(1, 2);
        struct TreeNode* node1 = createTreeNode(2, 0);
        struct TreeNode* node2 = createTreeNode(3, 1);
        struct TreeNode* node3 = createTreeNode(4, 0);
    
        root->children[0] = node1;
        root->children[1] = node2;
        node2->children[0] = node3;
    
        // 其他操作...
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.嵌套括号表示法

      嵌套括号表示法使用括号来表示树的结构:每对括号代表一个节点,而括号内的内容表示该节点的子节点。通过嵌套括号的方式,可以清晰地表示树的层次结构和节点之间的关系。

    tree_str = '((A (B C)) D)'
    
    • 1
    结构体
    #include 
    #include 
    
    struct TreeNode {
        int value;
        struct TreeNode* left;
        struct TreeNode* right;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    创建树
    struct TreeNode* createTreeNode(int value) {
        struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        node->value = value;
        node->left = NULL;
        node->right = NULL;
        return node;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    嵌套括号表示法
    // 根据嵌套括号表示法构建树
    struct TreeNode* buildTreeFromParenthesis(char* treeStr, int* index) {
        struct TreeNode* node = NULL;
        int value = 0;
        int sign = 1;
    
        while (treeStr[*index] != '\0') {
            char c = treeStr[*index];
            (*index)++;
    
            if (c == '(') {
                if (node == NULL) {
                    node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
                    node->left = NULL;
                    node->right = NULL;
                }
                node->left = buildTreeFromParenthesis(treeStr, index);
            } else if (c == ')') {
                return node;
            } else if (c == '-') {
                sign = -1;
            } else if (c >= '0' && c <= '9') {
                value = value * 10 + (c - '0');
            } else if (c == ' ') {
                value *= sign;
                node->value = value;
                value = 0;
                sign = 1;
            }
        }
    
        return node;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    主函数
    int main() {
        char* treeStr = "(1 (2 (4) (5)) (3 (6)))";
        int index = 0;
    
        struct TreeNode* root = buildTreeFromParenthesis(treeStr, &index);
    
        // 其他操作...
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.凹入表示法

      凹入表示法使用缩进来表示树的结构:每个节点都在上一级节点的下方,并且比上一级节点缩进一定的距离。通过缩进的方式,可以清晰地展示树的层次结构和节点之间的嵌套关系。

    结构体
    #include 
    #include 
    
    struct TreeNode {
        int value;
        struct TreeNode* firstChild;
        struct TreeNode* nextSibling;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    创建树
    struct TreeNode* createTreeNode(int value) {
        struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        node->value = value;
        node->firstChild = NULL;
        node->nextSibling = NULL;
        return node;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    凹入表示法
    struct TreeNode* buildTreeFromIndented(char* treeStr, int* index, int level) {
        struct TreeNode* node = NULL;
    
        while (treeStr[*index] != '\0') {
            char c = treeStr[*index];
            (*index)++;
    
            if (c == '\n') {
                continue;
            }
    
            if (c == ' ') {
                continue;
            }
    
            if (c == '-') {
                level++;
                continue;
            }
    
            int value = c - '0';
    
            if (node == NULL) {
                node = createTreeNode(value);
            } else {
                struct TreeNode* child = createTreeNode(value);
    
                if (node->firstChild == NULL) {
                    node->firstChild = child;
                } else {
                    struct TreeNode* sibling = node->firstChild;
    
                    while (sibling->nextSibling != NULL) {
                        sibling = sibling->nextSibling;
                    }
    
                    sibling->nextSibling = child;
                }
            }
    
            int nextChar = treeStr[*index];
    
            if (nextChar == '\n') {
                level--;
            } else if (nextChar == '-') {
                continue;
            } else {
                break;
            }
        }
    
        return node;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    主函数
    int main() {
        char* treeStr = "1\n-2\n--4\n--5\n-3\n--6\n";
        int index = 0;
    
        struct TreeNode* root = buildTreeFromIndented(treeStr, &index, 0);
    
        // 其他操作...
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    C#调用Windows API实现自定义打印纸张大小
    Zookeeper和Eureka的区别
    【鸿蒙】 模拟器运⾏
    MySQL学习指南&笔记&经典案例句
    普冉PY32系列(九) GPIO模拟和硬件SPI方式驱动无线收发芯片XL2400
    基于Java+SpringBoot+Thymeleaf+Mysql疫情疫苗预约系统学习系统设计与实现
    自定义 Hook(State Hook)_web前端培训
    MySQL【子查询】
    JAVA算法练习(10):绳圈
    前端js手写面试题汇总(一)
  • 原文地址:https://blog.csdn.net/m0_63834988/article/details/134234176