zoukankan      html  css  js  c++  java
  • 二叉树的各种操作

    二叉树的操作实现

    这里的二叉树全部都是用二叉链实现,算法都是一些简单的递归

    • 根据二叉树括号表示法字符串str生成对应的二叉树链式存储结构
    • 输出二叉树
    • 先序遍历、中序遍历、后序遍历
    • 销毁二叉树
    • 查找值为x的结点
    • 求二叉树的高度
    • 求二叉树元素的最大值
    • 求二叉树结点个数
    • 输出所有的叶子结点
    • 求二叉树中结点值x的层数
    • 求二叉树第k层的结点个数
    • 求第k层上叶子结点的个数
    • 求二叉树中所有单分支结点个数
    • 判断两棵树是否相似
    • 输出值为x的结点的所有祖先
    • 输出值为x的结点的所有子孙结点
    • 判断值为x的结点和值为y的结点是否为兄弟
    • 将二叉树b1复制到二叉树b2
    • 将二叉树的所有左右子树进行交换
    • 判断一颗二叉树是否是完全二叉树
      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 
      4 typedef char ElemType;
      5 typedef struct node 
      6 {
      7     ElemType data;
      8     struct node *lchild;
      9     struct node *rchild;
     10 }BTNode;
     11 
     12 const int MaxSize = 100 + 10;    
     13 
     14 //根据二叉树括号表示法字符串str生成对应的二叉树链式存储结构
     15 void CreateBTree(BTNode * &b, char *str)
     16 {
     17     BTNode *St[MaxSize], *p;        //St作为顺序栈
     18     int top = -1, k,j = 0;            //top作为栈顶指针
     19     char ch;
     20     b = NULL;
     21     ch = str[j];
     22     while (ch != '')
     23     {
     24         switch (ch)
     25         {
     26         case '(':top++; St[top] = p; k = 1; break;        //开始处理左孩子结点
     27         case ')':top--; break;                            //栈顶结点的子树处理完毕
     28         case ',':k = 2; break;                            //开始处理右孩子结点
     29         default:
     30             p = (BTNode *)malloc(sizeof(BTNode));        //创建一个结点,由p指向它
     31             p->data = ch;
     32             p->lchild = p->rchild = NULL;                
     33             if (b == NULL)  b = p;                        //若尚未创建根节点
     34             else
     35             {
     36                 switch (k)
     37                 {
     38                 case 1:St[top]->lchild = p; break;
     39                 case 2:St[top]->rchild = p; break;
     40                 }
     41             }
     42         }
     43         j++;                                            //继续扫描str
     44         ch = str[j];
     45     }
     46 }
     47 
     48 //输出二叉树DispBTree(b)
     49 void DispBTree(BTNode *b)
     50 {
     51     if (b != NULL)
     52     {
     53         printf("%c", b->data);
     54         if (b->lchild != NULL || b->rchild != NULL)
     55         {
     56             printf("(");                            //有孩子结点时才输出“(”
     57             DispBTree(b->lchild);                    //递归处理左子树
     58             if (b->rchild != NULL)  printf(",");    //有右孩子结点时才输出“,”
     59             DispBTree(b->rchild);                    //递归处理右子树
     60             printf(")");                            //有孩子结点时才输出
     61         }
     62     }
     63 }
     64 
     65 //先序遍历
     66 void PreOrder(BTNode * b)
     67 {
     68     if (b != NULL)
     69     {
     70         printf("%c", b->data);
     71         PreOrder(b->lchild);
     72         PreOrder(b->rchild);
     73     }
     74 }
     75 //中序遍历
     76 void InOrder(BTNode * b)
     77 {
     78     if (b != NULL)
     79     {
     80         InOrder(b->lchild);
     81         printf("%c", b->data);
     82         InOrder(b->rchild);
     83     }
     84 }
     85 //后序遍历
     86 void PostOrder(BTNode * b)
     87 {
     88     if (b != NULL)
     89     {
     90         InOrder(b->lchild);
     91         InOrder(b->rchild);
     92         printf("%c", b->data);
     93     }
     94 }
     95 
     96 //销毁二叉树
     97 void DestroyBTree(BTNode *& b)
     98 {
     99     if (b != NULL)
    100     {
    101         DestroyBTree(b->lchild);
    102         DestroyBTree(b->rchild);
    103         free(b);
    104     }
    105 }
    106 
    107 
    108 //查找值为x的结点
    109 BTNode *FindNode(BTNode *b, ElemType x)
    110 {
    111     BTNode *p;
    112     if (b == NULL)  return NULL;
    113     else if (b->data == x)  return b;
    114     else
    115     {
    116         p = FindNode(b->lchild, x);
    117         if (p != NULL)  return p;
    118         else  return FindNode(b->rchild, x);
    119     }
    120 }
    121 
    122 //求二叉树的高度
    123 int BTHeight(BTNode *b)
    124 {
    125     int lchildh, rchildh;
    126     if (b == NULL)  return 0;
    127     else
    128     {
    129         lchildh = BTHeight(b->lchild);
    130         rchildh = BTHeight(b->rchild);
    131         return lchildh > rchildh ? (lchildh + 1) : (rchildh + 1);
    132     }
    133 }
    134 
    135 //求二叉树元素的最大值
    136 int BTMax(BTNode *b)
    137 {
    138     if (b == NULL)  return 0;
    139     else
    140     {
    141         int m1 = BTMax(b->lchild);
    142         int m2 = BTMax(b->rchild);
    143         int m3 = b->data;
    144         if (m1 > m2)  return m1 > m3 ? m1 : m3;
    145         else  return m2 > m3 ? m2 : m3;
    146     }
    147 }
    148 
    149 //求二叉树结点个数
    150 int BTNum(BTNode * b)
    151 {
    152     if (b == NULL)  return 0;
    153     else  return BTNum(b->lchild) + BTNum(b->rchild) + 1;
    154 }
    155 
    156 //输出所有的叶子结点
    157 void DispLeaf(BTNode *b)
    158 {
    159     if (b != NULL)
    160     {
    161         if (b->lchild == NULL && b->rchild == NULL)
    162             printf("%c", b->data);
    163         DispLeaf(b->lchild);
    164         DispLeaf(b->rchild);
    165     }
    166 }
    167 
    168 //求二叉树中结点值x的层数
    169 //返回0表示未找到,h初始置为0
    170 int BTLevel(BTNode *b, ElemType x, int h)
    171 {
    172     int level;
    173     if (b == NULL)  return 0;
    174     else if (b->data == x)  return h;
    175     else
    176     {
    177         level = BTLevel(b->lchild, x, h + 1);
    178         if (level != 0)  return level;
    179         else  return BTLevel(b->rchild, x, h + 1);
    180     }
    181 }
    182 
    183 //求二叉树第k层的结点个数
    184 //当前层数h初始置为0
    185 int BTKlevel(BTNode *b,int h, int k)
    186 {
    187     if (b == NULL)  return 0;
    188     else
    189     {
    190         if (h == k)  return 1;
    191         if (h < k)   return (BTKlevel(b->lchild, h + 1, k) + BTKlevel(b->rchild,h + 1,k));
    192     }
    193 }
    194 
    195 //求第k层上叶子结点的个数
    196 int BTKlevelLeaf(BTNode *b, int h, int k)
    197 {
    198     if (b == NULL)  return 0;
    199     else
    200     {
    201         if (h == k && b->lchild == NULL && b->rchild == NULL)  return 1;
    202         if (h < k)   return (BTKlevelLeaf(b->lchild, h + 1, k) + BTKlevelLeaf(b->rchild, h + 1, k));
    203     }
    204     return 0;                //其它情况返回0
    205 }
    206 
    207 //求二叉树中所有单分支结点个数
    208 int BTSingleSonNode(BTNode * b)
    209 {
    210     if (b == NULL)  return 0;
    211     else if ((b->lchild == NULL && b->rchild != NULL) || (b->lchild != NULL && b->rchild == NULL))  return BTSingleSonNode(b->lchild) + BTSingleSonNode(b->rchild) + 1;
    212     else  return BTSingleSonNode(b->lchild) + BTSingleSonNode(b->rchild);
    213 }
    214 
    215 //判断两棵树是否相似
    216 //形态一样,结点值可以不同
    217 bool BTLike(BTNode *b1, BTNode *b2)
    218 {
    219     bool flag1, flag2;
    220     if (b1 == NULL && b2 == NULL)  return true;
    221     else if (b1 == NULL || b2 == NULL)  return false;
    222     else
    223     {
    224         flag1 = BTLike(b1->lchild, b2->lchild);
    225         flag2 = BTLike(b1->rchild, b2->rchild);
    226         return flag1 && flag2;
    227     }
    228 }
    229 
    230 //输出值为x的结点的所有祖先
    231 //f(b,x)=true表示以结点b为根节点的二叉树包含x
    232 bool BTAncestor(BTNode *b, ElemType x)
    233 {
    234     if (b == NULL)  return false;
    235     else if ((b->lchild != NULL && b->lchild->data == x) || (b->rchild != NULL && b->rchild->data == x))
    236     {
    237         printf("%c", b->data);
    238         return true;
    239     }
    240     else
    241     {
    242         int flag1 = BTAncestor(b->lchild, x);
    243         int flag2 = BTAncestor(b->rchild, x);        //考虑到可能存在多个x,分开写
    244         if(flag1 || flag2)  printf("%c", b->data);
    245         return true;
    246     }
    247     return false;
    248 }
    249 
    250 //输出值为x的结点的所有子孙结点
    251 void BTChild(BTNode *b, ElemType x)
    252 {
    253     if (b != NULL)
    254     {
    255         if (b->data == x)
    256         {
    257             PreOrder(b->lchild);
    258             PreOrder(b->rchild);
    259         }
    260         else
    261         {
    262             BTChild(b->lchild,x);
    263             BTChild(b->rchild,x);
    264         }
    265     }
    266 }
    267 
    268 //判断值为x的结点和值为y的结点是否为兄弟
    269 bool BTBrother(BTNode *b, ElemType x, ElemType y)
    270 {
    271     if (b == NULL)  return false;
    272     else
    273     {
    274         if (b->lchild != NULL && b->rchild != NULL)
    275             if ((b->lchild->data == x && b->rchild->data == y) || (b->lchild->data == y && b->rchild->data == x))
    276                 return true;
    277         return BTBrother(b->lchild, x, y) || BTBrother(b->rchild, x, y);
    278     }
    279 }
    280 
    281 //将二叉树b1复制到二叉树b2
    282 void BTCopy(BTNode *b1, BTNode * &b2)
    283 {
    284     if (b1 == NULL)      b2 = NULL;
    285     else
    286     {
    287         b2 = (BTNode *)malloc(sizeof(BTNode));
    288         b2->data = b1->data;
    289         BTCopy(b1->lchild, b2->lchild);
    290         BTCopy(b1->rchild, b2->rchild);
    291     }
    292 }
    293 
    294 //将二叉树的所有左右子树进行交换
    295 void BTSwap(BTNode *b1, BTNode * &b2)
    296 {
    297     if (b1 == NULL)  b2 = NULL;
    298     else
    299     {
    300         b2 = (BTNode *)malloc(sizeof(BTNode));
    301         b2->data = b1->data;
    302         BTSwap(b1->rchild, b2->lchild);
    303         BTSwap(b1->lchild, b2->rchild);
    304     }
    305 }
    306 
    307 
    308 //判断一颗二叉树是否是完全二叉树
    309 //两条规则,违反任意一条均不是完全二叉树
    310 //1、某结点无左孩子,则一定没有右孩子
    311 //2、若某结点缺少左孩子或右孩子,则其所有后继(层次遍历的后继)一定无孩子
    312 bool BTComp(BTNode *b)
    313 {
    314     BTNode *Qu[MaxSize], *p;            //定义一个队列用于层次遍历
    315     int front = 0, rear = 0;            //环形队列的队头和队尾指针
    316     bool cm = true;                        //cm为真表示二叉树为完全二叉树
    317     bool flag = true;                    //flag为真表示所有结点到目前为止都有左右孩子
    318     if (b == NULL)  return true;
    319     rear++;
    320     Qu[rear] = b;                        //根结点入队
    321     while (front != rear)                //队列不为空
    322     {
    323         front = (front + 1) % MaxSize;
    324         p = Qu[front];                    //队首出队
    325         if (p->lchild == NULL)  
    326         {
    327             flag = false;
    328             if (p->rchild != NULL)        //没有左孩子,则一定没有右孩子
    329             {
    330                 cm = false;
    331                 break;
    332             }
    333         }
    334         else
    335         {
    336             if ((!flag))                //出现空缺少左孩子或右孩子之后,所有的结点均无孩子
    337             {
    338                 cm = false;
    339                 break;
    340             }
    341             rear = (rear + 1) % MaxSize;
    342             Qu[rear] = p->lchild;            //左孩子入队
    343             if (p->rchild == NULL)  flag = false;
    344             else
    345             {
    346                 rear = (rear + 1) % MaxSize;
    347                 Qu[rear] = p->rchild;        //右孩子入队
    348             }
    349         }
    350     }
    351     return cm;
    352 }
    353 
    354 int main()
    355 {
    356     BTNode *b1, *b2;
    357     char str1[] = "A(B(D(,G)),C(E(,G),F))";
    358     char str2[] = "A(B(D,D),C(E))";
    359     CreateBTree(b2,str2);
    360     printf("%d
    ", BTComp(b2));
    361     return 0;
    362 }

    参考资料:《数据结构教程》李春葆等

  • 相关阅读:
    微信小程序用setData修改数组或对象中的一个属性值,超好用,最简单的实现方法,不容错过!大神们 都 在 看 的方法!!!
    pythonchallenge1
    pythonchallenge4
    pythonchallenge7
    pythonchallenge9
    pythonchallenge8
    pythonchallenge2
    pythonchallenge0
    递归排序
    pythonchallenge3
  • 原文地址:https://www.cnblogs.com/lfri/p/10256069.html
Copyright © 2011-2022 走看看