普通树型结构

树型结构:

    1.树的基本概念

    一种表示层次关系(一对多)的数据结构

    有且只有一个特定的特点,该节点没有前驱节点,被称为根节点

    剩余的n个互不相交的子集,其中每个子集也都是一棵树,都被称为根节点的子树

    注意:树型结构具有递归性(树中有树)

    2.树的表示方式:

        倒悬树、嵌套法、凹凸法

    3.树的专业术语

        节点:组成树的基础元素、同时它也是一棵树

        节点的度:该节点子树的数量

        树的度:树中所有节点的度的最大值

        树的深度(高度):树的最大层次为树的深度

        节点的层次:根节点的层次为1,它的孩子层次为2,孩子的孩子层次为3,以此类推

        叶子节点:节点的度为0的节点

        双亲节点和孩子节点:节点的子树被称为该节点的孩子节点,该节点就是孩子的双亲节点

        兄弟节点:具有同一个双亲节点的节点互为兄弟节点

        堂兄弟节点:双亲节点互为兄弟节点

        祖先:从根节点出发到该节点,路径上经过的所有节点都被称为该节点的祖先

        子孙:一个节点的子树中任意一个节点都是它的子孙

    4.树的存储

        树可以顺序存储、链式存储,还可以混合存储

        可以根据存储的信息不同,树有以下存储方式

        双亲表示法:          顺序

            位置     data   双亲下标

             0        A       -1

             1        B        0

             2        C        0

             3        D        1

             4        E        1

             5        F        1

             6        G        2

             7        H        4

             优点:方便找到双亲

             缺点:查找孩子结点麻烦

pppp

        孩子表示法:

            顺序:    浪费内存

            位置    data    son_arr(存储子节点的数量)

             0        A       1,2,8

             1        B       3,4,5

             2        C       6

             3        D        

             4        E       7

             5        F        

             6        G        

             7        H        



 

            链式:    节约内存空间

             位置    data    ListHead(存储子节点的链表)

             0        A       1->2->8->NULL

             1        B       3->4->5->NULL

             2        C       6->NULL

             3        D       NULL

             4        E       7->NULL

             5        F       NULL

             6        G       NULL

             7        H       NULL

             优点:查找孩子节点方便

             缺点:找双亲不方便

        兄弟表示法:

            链式

            双亲只存储第一个子节点   数据    链式指向所有兄弟节点

            优点:可以方便找到所有的兄弟节点

            缺点:找双亲麻烦

        注意:普通树不常用 ,一般会使用二叉树进行存储



 

双亲表示法:

#include <stdio.h>

#include <stdlib.h>

#include <stdbool.h>

//  顺序存储 双亲表示法

typedef struct TreeNode

{

    char data;      //  数据

    int parent;     //  双亲节点下标

}TreeNode;

//  设计顺序结构存储一棵树

typedef struct Tree

{

    TreeNode* arr;  //  存储节点内存的首地址

    size_t cal;     //  容量

    size_t cnt;     //  数量

}Tree;

//  创建树

Tree* create_tree(size_t cal)

{

    Tree* tree = malloc(sizeof(Tree));

    tree->arr = malloc(sizeof(TreeNode)*cal);

    tree->cal = cal;

    tree->cnt = 0;

    return tree;

}

//  添加结点 data要加入的数据  parent是双亲数据

bool add_tree(Tree* tree,char data,char parent)

{

    //  树不存在满 可以扩容

    if(tree->cnt >= tree->cal)

    {

        tree->cal *= 2;

        tree->arr =

         realloc(tree->arr,(tree->cal)*sizeof(TreeNode));

    }

    //  根节点没有双亲,约定它双亲为 '\0'

    if('\0' == parent && 0 == tree->cnt)

    {

        tree->arr[0].data = data;

        tree->arr[0].parent = -1;

        tree->cnt++;

        return true;

    }

    for(int i=0; i<tree->cnt; i++)

    {

        if(parent == tree->arr[i].data)

        {

            tree->arr[tree->cnt].data = data;

            tree->arr[tree->cnt++].parent = i;

            return true;

        }

    }

    return false;

}

void show_tree(Tree* tree)

{

    for(int i=0; i<tree->cnt; i++)

    {

        printf("index:%d data:%c parent:%d\n",

            i,tree->arr[i].data,tree->arr[i].parent);  

    }

}

//  计算节点的度

int node_count(Tree* tree,char data)

{

    int index = -1,count = 0;

    for(int i=0; i<tree->cnt; i++)

    {

        if(data == tree->arr[i].data) index = i;

    }

    if(-1 == index) return -1;

   

    for(int i=0; i<tree->cnt; i++)

    {

        if(index == tree->arr[i].parent) count++;

    }

    return count;

}

//  计算节点data的高度

int _high_tree(Tree* tree,char data)

{

    int index = -1;

    for(int i=0; i<tree->cnt; i++)

    {

        if(data == tree->arr[i].data)

        {

            index = i;  

            break;

        }

    }

    if(-1 == index) return -1;

    int son_high_max = 0;

    for(int i=0; i<tree->cnt; i++)

    {

        if(index == tree->arr[i].parent)

        {

            int high = _high_tree(tree,tree->arr[i].data);

            if(high > son_high_max) son_high_max = high;

        }

    }

    return son_high_max + 1;

}

//  计算树的高度

int high_tree(Tree* tree)

{

    return _high_tree(tree,tree->arr[0].data);

}


 

int main(int argc,const char* argv[])

{

    Tree* tree = create_tree(10);

    add_tree(tree,'A','\0');

    add_tree(tree,'B','A');

    add_tree(tree,'C','A');

    add_tree(tree,'D','B');

    add_tree(tree,'E','B');

    add_tree(tree,'F','B');

    add_tree(tree,'G','C');

    add_tree(tree,'H','E');

    add_tree(tree,'X','A');

    add_tree(tree,'Y','H');

    show_tree(tree);

    printf("son_count=%d\n",node_count(tree,'C'));

    printf("tree_high=%d\n",high_tree(tree));

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyu1381

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值