• 家谱图-二叉树


    因为树有多种表示方式,也可以不用二叉树来表示,但是那样有局限性, 就比如一个节点有几个孩子,这个数目都是不确定的,如果用二叉树来表示,那样就比较清楚的显示出家谱中的人员组成,但是不能用孩子表示法,因为那样最多只能表示两个孩子,但是可以转化一下表示方法,用孩子兄弟表示方法来表示,那样,就可以有无限多个(理论上)孩子,就是一个节点有两个指针,一个指向第一个孩子,一个指向它的右兄弟,所以,这种二叉树可以表示好多方式,其实和那种二叉树一样,只是解释不一样了而已,在计算机中更是差不多,因为计算机没有这些逻辑,这些都是我们为了方便而想象出来的,家谱图主要实现的功能有增加节点,查询一个节点的子节点,删除一个节点(同时删除)它的子树。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 typedef char TElemType;
      5 
      6 //孩子兄弟表示法
      7 typedef struct Tree{
      8     TElemType data;
      9     struct Tree *firstchild, *rightbro;
     10 }CSNode, *PCSTree;
     11 
     12 PCSTree ptr;
     13 char data;
     14 
     15 void createTree(PCSTree *T)//创建二叉树
     16 {
     17     TElemType data;
     18     scanf("%c", &data);
     19     getchar();
     20     if(data == ' ')
     21         *T = NULL;
     22     else
     23     {
     24         *T = (PCSTree)malloc(sizeof(CSNode));
     25         (*T) -> data = data;
     26         printf("Please input %c's first child
    ", data);
     27         createTree(&(*T) -> firstchild);
     28         printf("Please input %c's right brother
    ", data);
     29         createTree(&(*T) -> rightbro);
     30     }
     31 }
     32 
     33 void preOrderTraverse(PCSTree T)//前续遍历
     34 {
     35     if(T == NULL)
     36         return ;
     37     printf("%c ", T -> data);
     38     preOrderTraverse(T -> firstchild);
     39     preOrderTraverse(T -> rightbro);
     40 }
     41 
     42 void findChild(PCSTree T, char data)//查找某个节点的孩子
     43 {
     44     if (T == NULL)
     45         return ;
     46     PCSTree p;
     47     p = T->firstchild;
     48     if (T->data == data)
     49     {
     50         if(p == NULL)
     51         {
     52             printf("No member!
    ");
     53             return;
     54         }
     55         while (p->rightbro != NULL)//打印出来他所有的孩子
     56         {
     57             printf("%c ", p->data);
     58             p = p->rightbro;
     59         }
     60         printf("%c
    ", p->data);
     61         return ;
     62     }
     63     else
     64     {
     65         findChild(T->firstchild, data);//如果找不到的话,继续找他的子节点
     66         findChild(T->rightbro, data);
     67     }
     68 }
     69 
     70 int addMember(PCSTree *T)//添加新成员
     71 {
     72     if(*T == NULL)//用于递归时判断退出条件
     73         return 0;
     74     PCSTree pt;
     75     if ((*T)->data == data)//找到父节点
     76     {
     77         if ((*T)->firstchild != NULL)
     78         {
     79             pt = (*T)->firstchild;
     80             while(pt->rightbro != NULL)//找到最右边的一个添加新节点
     81                 pt = pt->rightbro;
     82             pt->rightbro = ptr;
     83             return 1;//添加成功, 返回1
     84         }
     85         (*T)->firstchild = ptr;
     86         return 1;
     87     }
     88 
     89     if (addMember(&(*T)->firstchild) == 1)//递归再找匹配的父节点
     90         return 1;
     91     if (addMember(&(*T)->rightbro) == 1)
     92         return 1;
     93     return 0;
     94 }
     95 
     96 void findAndFree(PCSTree *T)//找到传过来的某个节点并且将它释放掉,并且释放掉它所有的子节点
     97 {
     98     if(*T == NULL)
     99         return;
    100     PCSTree p1, p2;
    101     p1 = (*T)->firstchild;
    102     p2 = (*T)->rightbro;
    103     findAndFree(&p1);
    104     findAndFree(&p2);
    105     free(*T);
    106 }
    107 
    108 int deleteMember(PCSTree *T)//删除节点函数(删除其子树)
    109 {
    110     PCSTree pt;
    111     if(*T == NULL)
    112         return 0;
    113     //类似链表中的删除,要删除当前元素,先要找到它的前一个
    114     if((*T)->firstchild == NULL && (*T)->rightbro == NULL)
    115     {
    116         if ((*T)->data == data)
    117         {
    118             free(*T);
    119             return 1;
    120         }
    121         return 0;
    122     }
    123     //如果是它的子节点
    124     if((*T)->firstchild != NULL && (*T)->firstchild->data == data)
    125     {
    126         pt = (*T)->firstchild;
    127         if (pt->rightbro != NULL)
    128         {
    129             (*T)->firstchild = pt->rightbro;
    130         }
    131         else
    132             (*T)->firstchild = NULL;
    133         if(pt->firstchild != NULL)
    134             findAndFree(&(pt->firstchild));
    135         free(pt);
    136         return 1;
    137     }
    138     //如果是它的右兄弟节点
    139     else if ((*T)->rightbro != NULL && (*T)->rightbro->data == data)
    140     {
    141         pt = (*T)->rightbro;
    142         if (pt->rightbro != NULL)
    143         {
    144              (*T)->rightbro = pt->rightbro;
    145 
    146         }
    147         else
    148             (*T)->rightbro = NULL;
    149         if(pt->firstchild != NULL)
    150             findAndFree(&(pt->firstchild));
    151         free(pt);
    152         return 1;
    153     }
    154     //如果都不是,继续递归 找
    155     if(deleteMember(&(*T)->firstchild))
    156         return 1;
    157     if(deleteMember(&(*T)->rightbro))
    158         return 1;
    159     return 0;
    160 }
    161 
    162 
    163 int main()
    164 {
    165 //    freopen("in.txt", "r", stdin);
    166     PCSTree T;
    167     printf("Input root Node:
    ");
    168     createTree(&T);//create binary tree
    169     printf("The previous traverse are:
    ");
    170     preOrderTraverse(T);//previous traverse the tree
    171     printf("
    ");
    172     char newdata;
    173     int choice;
    174     do{
    175         printf("1. find some node's kids   2. add member
    ");
    176         printf("3. delete some node        4. previous traverse the tree
    ");
    177         printf("0. exit
    ");
    178         scanf("%d", &choice);
    179         switch(choice)
    180         {
    181             case 1:
    182                 printf("
    Please input you want find child name:
    ");
    183                 getchar();
    184                 scanf("%c", &data);
    185                 findChild(T, data);
    186                 printf("
    ");
    187                 break;
    188             case 2:
    189                 if(T == NULL)
    190                 {
    191                     printf("Input root node:
    ");
    192                     getchar();
    193                     createTree(&T);
    194                 }
    195                 else
    196                 {
    197                     printf("Please input you want add data
    ");
    198                     printf("Format: father child
    ");
    199                     ptr = (PCSTree)malloc(sizeof(CSNode));
    200                     ptr->firstchild = ptr->rightbro = NULL;
    201                     getchar();
    202                     scanf("%c %c", &data, &newdata);
    203                     ptr->data = newdata;
    204                     addMember(&T);
    205                     preOrderTraverse(T);
    206                     printf("
    ");
    207                 }
    208                 break;
    209             case 3:
    210                 if(T == NULL)
    211                 {
    212                     printf("No member
    ");
    213                     break;
    214                 }
    215                 printf("Please input you want delete node
    ");
    216                 getchar();
    217                     scanf("%c", &data);
    218                 if(data == T->data)
    219                 {
    220                     findAndFree(&T);
    221                     T = NULL;
    222                 }
    223                 else
    224                     deleteMember(&T);
    225                 break;
    226             case 4:
    227                 if(T != NULL)
    228                     preOrderTraverse(T);
    229                 else
    230                     printf("No member");
    231                 printf("
    ");
    232                 break;
    233             default:
    234                 break;
    235         }
    236     }while(choice != 0);
    237     return 0;
    238 }
  • 相关阅读:
    [HNOI2009]梦幻布丁(链表+启发式合并)
    [HNOI2004]宠物收养场(Treap)
    【模板】Treap
    Monkey King(左偏树)
    【模板】左偏树
    数列分段Section II(二分)
    [HAOI2006]受欢迎的牛(tarjan缩点)
    【模板】树链剖分
    精美产品策划类企业织梦模板
    简洁的支持展开关闭的tab标签代码
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4009542.html
Copyright © 2020-2023  润新知