• 树的定义和操作


    头文件

    #include <stdio.h>
    #include <stdlib.h>
    

    结构体

    /*
     * 值类型
     */
    typedef int datatype;
    
    /*
     * 节点结构体
     */
    typedef struct node
    {
        datatype value;
        struct node *left;  /* 左节点 */
        struct node *right; /* 右节点 */
    } Node;
    
    /*
     * 树根 root 节点
     */
    typedef struct tree
    {
        Node *root;
    } Tree;
    

    main() 函数

    int main()
    {
        datatype datas[] = {4, 5, 3, 9, 2, 3};
        int data_size = sizeof(datas) / sizeof(datas[0]);
        Tree tree;
        tree.root = NULL;
    
        int i = 0;
        // 数据
        printf("输入数据: ");
        for (i = 0; i < data_size; i++)
        {
            printf("%d, ", datas[i]);
        }    
        // 插入
        for (i = 0; i < data_size; i++)
        {
            insert(&tree, datas[i]);
        }
        printf("
    ");
        // 深度
        printf("树深度:%d 
    ", depth(tree.root));
        // 双孩子节点个数
        printf("双孩子个数:%d 
    ", twoSonCount(tree.root));
        // 单孩子节点个数
        printf("单孩子个数:%d 
    ", singleSonCount(tree.root));
        // 节点总数
        printf("节点总数: %d 
    ", nodeCount(tree.root));
        // 叶子节点总数
        printf("叶子节点总数: %d 
    ", leafNodeCount(tree.root));
    
        // 遍历
        printf("前序遍历: ");
        preOrderRecursive(tree.root);
        printf("
    ");
        printf("后序遍历: ");
        postOrderRecursive(tree.root);
        printf("
    ");
        printf("中序遍历: ");
        inOrderRecursive(tree.root);
        printf("
    ");
        // 销毁
        printf("销毁节点: ");
        destory(tree.root);
        printf("
    ");
    
        return 0;
    }
    

    插入

    void insert(Tree *tree, datatype value)
    {
        Node *newNode = (Node *)malloc(sizeof(Node));
        newNode->value = value;
        newNode->left = NULL;
        newNode->right = NULL;
    
        if (tree->root == NULL)
        {
            tree->root = newNode;
        }
        else
        {
            Node *tmp = tree->root;
            while (tmp != NULL) 
            {
                if(value < tmp->value)
                { /* 左节点 */
                    if(tmp->left == NULL)
                    {
                        tmp->left = newNode;
                        return;
                    }
                    else
                    {
                        tmp = tmp->left;                   
                    }
                    
                }
                else
                { /* 右节点 */
                    if(tmp->right == NULL)
                    {
                        tmp->right = newNode;
                        return;
                    }
                    else
                    {
                        tmp = tmp->right;
                    }
                }
            }       
        }
    }
    

    销毁树

    销毁树需要采用后序遍历销毁,要不然会出现节点丢失,没有销毁的情况。

    void destory(Node *node)
    {
        if (node != NULL)
        {
            destory(node->left);
            destory(node->right);
            printf("%d, ", node->value);
            free(node);
            node = NULL;
        }
    }
    

    遍历树

    前序遍历

    void preOrderRecursive(Node *node)
    {
        if (node != NULL)
        {
            printf("%d, ", node->value);
            preOrderRecursive(node->left);
            preOrderRecursive(node->right);
        }   
    }
    

    中序遍历

    void inOrderRecursive(Node *node)
    {
        if(node != NULL)
        {
            inOrderRecursive(node->left);
            printf("%d, ", node->value);
            inOrderRecursive(node->right);
        }
    }
    

    后序遍历

    void postOrderRecursive(Node *node) {
        if (node != NULL)
        {
            postOrderRecursive(node->left);
            postOrderRecursive(node->right);
            printf("%d, ", node->value);
        }
        
    }
    

    树的深度

    int depth(Node *node)
    {
        int leftDepth = 0, rightDepth = 0;
        if(node == NULL)
        {
            return 0;
        }
        else
        {
            leftDepth = depth(node->left);
            rightDepth = depth(node->right);
        }
        if (leftDepth > rightDepth)
        {
            return (leftDepth + 1);
        }
        else
        {
            return rightDepth + 1;
        }
    }
    

    节点总数

    int nodeCount(Node *node)
    {
        if (node == NULL)
        {
            return 0;
        }
        else
        {
            return (nodeCount(node->left) + nodeCount(node->right) + 1);
        }   
    }
    

    双孩子节点个数

    int twoSonCount(Node *node)
    {
        if (node == NULL)
        {
            return 0;
        }
        else if (node->left == NULL || node->right == NULL)
        {
            return (twoSonCount(node->left) + twoSonCount(node->right));
        }
        else
        {
            return (twoSonCount(node->left) + twoSonCount(node->right) + 1);
        }
    }
    

    单孩子节点个数

    int singleSonCount(Node *node)
    {
        if (node == NULL)
        {
            return 0;
        }
        else if(node->left == NULL && node->right == NULL)
        {
            return 0;
        }
        else if (node->left != NULL && node->right != NULL)
        {
            return (singleSonCount(node->left) + singleSonCount(node->right));
        }
        else
        {
            return (1 + singleSonCount(node->left) + singleSonCount(node->right));
        }
    }
    

    叶子节点个数

    叶子节点又叫终端节点

    int leafNodeCount(Node *node)
    {
        if (node == NULL)
        {
            return 0;
        }
        else if(node->left == NULL && node->right == NULL)
        {
            return 1;
        }
        else
        {
            return (leafNodeCount(node->left) + leafNodeCount(node->right));
        }   
    }
    
  • 相关阅读:
    IO复用三种方式
    sql server如何通过pivot对数据进行行列转换(进阶)
    sql server排序规则冲突问题解决
    sql server如何通过pivot对数据进行行列转换
    sql server如何通过排序控制insert into ... select ... 语句的记录插入顺序
    sql server如何用不同语种语言显示报错的错误消息
    Python编程求解第1天1分钱之后每天两倍持续一个月的等比数列问题
    sql server临时删除/禁用非聚集索引并重新创建加回/启用的简便编程方法研究对比
    sql server通过临时存储过程实现使用参数添加文件组脚本复用
    sql server重建全库索引和更新全库统计信息通用脚本
  • 原文地址:https://www.cnblogs.com/newber/p/14192153.html
Copyright © 2020-2023  润新知