博学之,审问之,慎思之,明辨之,笃行之!

导航

树的定义和操作

头文件

#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("\n");
    // 深度
    printf("树深度:%d \n", depth(tree.root));
    // 双孩子节点个数
    printf("双孩子个数:%d \n", twoSonCount(tree.root));
    // 单孩子节点个数
    printf("单孩子个数:%d \n", singleSonCount(tree.root));
    // 节点总数
    printf("节点总数: %d \n", nodeCount(tree.root));
    // 叶子节点总数
    printf("叶子节点总数: %d \n", leafNodeCount(tree.root));

    // 遍历
    printf("前序遍历: ");
    preOrderRecursive(tree.root);
    printf("\n");
    printf("后序遍历: ");
    postOrderRecursive(tree.root);
    printf("\n");
    printf("中序遍历: ");
    inOrderRecursive(tree.root);
    printf("\n");
    // 销毁
    printf("销毁节点: ");
    destory(tree.root);
    printf("\n");

    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));
    }   
}

posted on 2020-12-26 12:49  PP杰  阅读(124)  评论(0编辑  收藏  举报