• 5.3二叉树的运算


    5.3.2二叉树的遍历

    (1)前序遍历二叉树的递归定义

    若二叉树非空,则依次进行操作:1 访问根结点;2 前序遍历左子树;3 前序遍历右子树。

    (2)中序遍历二叉树的递归定义

    若二叉树非空,则依次进行操作:1 中序遍历左子树;2 访问根结点;3 中序遍历右子树。

    (3)后序遍历二叉树的递归定义

    若二叉树非空,则依次进行操作:1 后序遍历左子树;2 后序遍历右子树;3 访问根结点。

    C实现

    image

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 typedef char DataType;
     5 
     6 struct node
     7 {
     8     DataType data;
     9     struct node * lchild, *rchild;
    10 };
    11 typedef struct node BinTNode;
    12 
    13 BinTNode * CreateBinTree();//二叉树的生成
    14 void Preorder(BinTNode * bt);//前序遍历二叉链表算法
    15 void Inorder(BinTNode * bt);//中序遍历二叉链表算法
    16 void Postorder(BinTNode * bt);//后序遍历二叉链表算法
    17 
    18 void main()
    19 {
    20     BinTNode * bt = CreateBinTree();//二叉树的生成
    21 
    22     Preorder(bt);//前序遍历二叉链表算法
    23     printf("
    ");
    24 
    25     Inorder(bt);//中序遍历二叉链表算法
    26     printf("
    ");
    27 
    28     Postorder(bt);//后序遍历二叉链表算法
    29     printf("
    ");
    30 
    31     system("pause");
    32 }
    33 
    34 BinTNode * CreateBinTree()
    35 {
    36     BinTNode * pa = (BinTNode *)malloc(sizeof(BinTNode));
    37     BinTNode * pb = (BinTNode *)malloc(sizeof(BinTNode));
    38     BinTNode * pc = (BinTNode *)malloc(sizeof(BinTNode));
    39     BinTNode * pd = (BinTNode *)malloc(sizeof(BinTNode));
    40     BinTNode * pe = (BinTNode *)malloc(sizeof(BinTNode));
    41 
    42     pa->data = 'A';
    43     pb->data = 'B';
    44     pc->data = 'C';
    45     pd->data = 'D';
    46     pe->data = 'E';
    47 
    48     pa->lchild = pb;
    49     pa->rchild = pc;
    50     pb->lchild = pb->rchild = NULL;
    51     pc->lchild = pd;
    52     pc->rchild = NULL;
    53     pd->lchild = NULL;
    54     pd->rchild = pe;
    55     pe->lchild = pe->rchild = NULL;
    56 
    57     return pa;
    58 }
    59 
    60 void Preorder(BinTNode * bt)//前序遍历二叉链表算法
    61 {
    62     if (bt != NULL)
    63     {
    64         printf("%c", bt->data);//访问根结点
    65         Preorder(bt->lchild);//前序遍历左子树
    66         Preorder(bt->rchild);//前序遍历右子树
    67     }
    68 }
    69 
    70 void Inorder(BinTNode * bt)//中序遍历二叉链表算法
    71 {
    72     if (bt != NULL)
    73     {
    74         Inorder(bt->lchild);//中序遍历左子树
    75         printf("%c", bt->data);//访问根结点
    76         Inorder(bt->rchild);//中序遍历右子树
    77     }
    78 }
    79 
    80 void Postorder(BinTNode * bt)//后序遍历二叉链表算法
    81 {
    82     if (bt != NULL)
    83     {
    84         Postorder(bt->lchild);//后序遍历左子树
    85         Postorder(bt->rchild);//后序遍历右子树
    86         printf("%c", bt->data);//访问根结点
    87     }
    88 }

    输出结果

    ABCDE
    BADEC
    BEDCA
    请按任意键继续. . .

    1递归遍历算法

    2非递归遍历算法

    C++实现

    void Preorder(BinTNode *bt);//前序遍历二叉链表算法
    void Inorder(BinTNode *bt);//中序遍历二叉链表算法
    void Postorder(BinTNode *bt);//后序遍历二叉链表算法
    void Inorder1(BinTNode *bt);//利用栈的非递归中序遍历算法
    void Inorder2(BinTNode *bt);//用指针数组来实现二叉树非递归中序遍历算法
    int getyenum(BinTNode *bt);//统计叶子结点数量
    int BinTreeDepth(BinTNode *bt);//二叉树的深度
    void TransLevel(BinTNode *bt);//非递归的按层遍历二叉链表树
    int getfather(BinTNode *bt, int num);//查找二叉树的父结点
    int getleft(BinTNode *bt, int num);//查找二叉树的某个结点的左兄弟
    int findmax(BinTNode *bt);//查找二叉树的最大值
    BinTNode *insertnode(BinTNode *bt, int num);//二叉树插入

      1 #include <iostream>
      2 #include <stack>
      3 #include <queue>
      4 
      5 typedef struct node
      6 {
      7     int data;
      8     struct node *lchild = nullptr, *rchild = nullptr;
      9 }BinTNode;
     10 
     11 void Preorder(BinTNode *bt);//前序遍历二叉链表算法
     12 void Inorder(BinTNode *bt);//中序遍历二叉链表算法
     13 void Postorder(BinTNode *bt);//后序遍历二叉链表算法
     14 void Inorder1(BinTNode *bt);//利用栈的非递归中序遍历算法
     15 void Inorder2(BinTNode *bt);//用指针数组来实现二叉树非递归中序遍历算法
     16 int getyenum(BinTNode *bt);//统计叶子结点数量
     17 int BinTreeDepth(BinTNode *bt);//二叉树的深度
     18 void TransLevel(BinTNode *bt);//非递归的按层遍历二叉链表树
     19 int getfather(BinTNode *bt, int num);//查找二叉树的父结点
     20 int getleft(BinTNode *bt, int num);//查找二叉树的某个结点的左兄弟
     21 int findmax(BinTNode *bt);//查找二叉树的最大值
     22 BinTNode *insertnode(BinTNode *bt, int num);//二叉树插入
     23 
     24 void main()
     25 {
     26     BinTNode *root;
     27 
     28     BinTNode s1;
     29     BinTNode s2;
     30     BinTNode s3;
     31     BinTNode s4;
     32     BinTNode s5;
     33     BinTNode s6;
     34     BinTNode s7;
     35 
     36     root = &s1;
     37 
     38     s1.data = 1;
     39     s2.data = 2;
     40     s3.data = 3;
     41     s4.data = 4;
     42     s5.data = 5;
     43     s6.data = 6;
     44     s7.data = 7;
     45 
     46     s1.lchild = &s2;
     47     s1.rchild = &s3;
     48     s2.lchild = &s4;
     49     s2.rchild = &s5;
     50     s3.lchild = &s6;
     51     s3.rchild = &s7;
     52 
     53     Preorder(root);//前序遍历二叉链表算法
     54     std::cout << "
    ";
     55     Inorder(root);//中序遍历二叉链表算法
     56     std::cout << "
    ";
     57     Postorder(root);//后序遍历二叉链表算法
     58     std::cout << "
    ";
     59 
     60     Inorder1(root);//利用栈的非递归中序遍历算法
     61     std::cout << "
    ";
     62 
     63     Inorder2(root);//用指针数组来实现二叉树非递归中序遍历算法
     64     std::cout << "
    ";
     65 
     66     std::cout << getyenum(root) << std::endl;//统计叶子结点数量
     67 
     68     std::cout << BinTreeDepth(root) << std::endl;//二叉树的深度
     69 
     70     TransLevel(root);//非递归的按层遍历二叉链表树
     71     std::cout << "
    ";
     72 
     73     std::cout << getfather(root, 3) << std::endl;//查找二叉树的父结点
     74 
     75     std::cout << getleft(root, 3) << std::endl;//查找二叉树的某个结点的左兄弟
     76 
     77     std::cout << findmax(root) << std::endl;//查找二叉树的最大值
     78 
     79     insertnode(root, 8);//二叉树插入
     80     root = &s1;
     81     Inorder(root);//中序遍历二叉链表算法
     82     std::cout << "
    ";
     83 }
     84 
     85 void main2()
     86 {
     87     BinTNode *root;
     88     BinTNode array[100];
     89 
     90     for (int i = 0; i < 100; i++)
     91     {
     92         array[i].data = i;
     93     }
     94 
     95     for (int i = 0; i < 99 / 2; i++)
     96     {
     97         array[i].lchild = &array[2 * i + 1];
     98         array[i].rchild = &array[2 * i + 2];
     99     }
    100 
    101     root = &array[0];
    102 
    103     Preorder(root);//前序遍历二叉链表算法
    104 }
    105 
    106 void Preorder(BinTNode *bt)//前序遍历二叉链表算法
    107 {
    108     if (bt != NULL)
    109     {
    110         std::cout << bt->data << " ";
    111         Preorder(bt->lchild);
    112         Preorder(bt->rchild);
    113     }
    114 }
    115 
    116 void Inorder(BinTNode *bt)//中序遍历二叉链表算法
    117 {
    118     if (bt != NULL)
    119     {
    120         Inorder(bt->lchild);
    121         std::cout << bt->data << " ";
    122         Inorder(bt->rchild);
    123     }
    124 }
    125 
    126 void Postorder(BinTNode *bt)//后序遍历二叉链表算法
    127 {
    128     if (bt != NULL)
    129     {
    130         Postorder(bt->lchild);
    131         Postorder(bt->rchild);
    132         std::cout << bt->data << " ";
    133     }
    134 }
    135 
    136 void Inorder1(BinTNode *bt)//利用栈的非递归中序遍历算法
    137 {
    138     std::stack<BinTNode *>S;
    139     BinTNode *p;
    140     S.push(bt);
    141 
    142     while (!S.empty())
    143     {
    144         while (S.top())
    145         {
    146             S.push(S.top()->lchild);//直到左子树空为止
    147         }
    148 
    149         p = S.top();
    150         S.pop();//空指针退栈
    151         
    152         if (!S.empty())
    153         {
    154             std::cout << S.top()->data << " ";//访问根结点
    155 
    156             p = S.top();
    157             S.pop();
    158             
    159             S.push(p->rchild);//右子树进栈
    160         }
    161     }
    162 }
    163 
    164 void Inorder2(BinTNode *bt)//用指针数组来实现二叉树非递归中序遍历算法
    165 {
    166     BinTNode *ST[100];//用指针数组模拟栈
    167     int top = 0;//初始化数组
    168     ST[top] = bt;
    169 
    170     do
    171     {
    172         while (ST[top] != NULL)//根结点及其所有的左结点地址装入数组
    173         {
    174             top++;
    175             ST[top] = ST[top - 1]->lchild;
    176         }
    177         top = top - 1;
    178         if (top >= 0)//判数组中地址是否访问完
    179         {
    180             std::cout << ST[top]->data << " ";//访问结点
    181             ST[top] = ST[top]->rchild;//扫描右子树
    182         }
    183     } while (top != -1);
    184 }
    185 
    186 int getyenum(BinTNode *bt)//统计叶子结点数量
    187 {
    188     int left = 0;
    189     int right = 0;
    190     if (!bt)
    191     {
    192         return 0;
    193     }
    194     if (!bt->lchild && !bt->rchild)
    195     {
    196         return 1;
    197     }
    198     left = getyenum(bt->lchild);
    199     right = getyenum(bt->rchild);
    200     return left + right;
    201 }
    202 
    203 int BinTreeDepth(BinTNode *bt)//二叉树的深度
    204 {
    205     int depl, depr;
    206     if (!bt)
    207     {
    208         return 0;
    209     }
    210     else
    211     {
    212         depl = BinTreeDepth(bt->lchild);
    213         depr = BinTreeDepth(bt->rchild);
    214         if (depl > depr)
    215         {
    216             return depl + 1;
    217         }
    218         else
    219         {
    220             return depr + 1;
    221         }
    222     }
    223 }
    224 
    225 void TransLevel(BinTNode *bt)//按层遍历二叉树,从上到下,从左到右
    226 {
    227     std::queue<BinTNode *>myqueue;
    228     if (!bt)//二叉树为空,返回
    229     {
    230         return;
    231 
    232     }
    233     else
    234     {
    235         std::cout << bt->data << " ";//输出根结点
    236         myqueue.push(bt);//根结点指针入队
    237         while (!myqueue.empty())
    238         {
    239             bt = myqueue.front();
    240             myqueue.pop();//出队列
    241             if (bt->lchild)
    242             {
    243                 std::cout << bt->lchild->data << " ";//输出左子树根结点
    244                 myqueue.push(bt->lchild);//左子数入队列
    245             }
    246             if (bt->rchild)
    247             {
    248                 std::cout << bt->rchild->data << " ";//输出右子树根结点
    249                 myqueue.push(bt->rchild);//右子数入队列
    250             }
    251         }
    252     }
    253 }
    254 
    255 int getfather(BinTNode *bt, int num)//查找二叉树的父结点
    256 {
    257     if (!bt)
    258     {
    259         return 0;
    260     }
    261     if (bt->lchild && bt->lchild->data == num)
    262     {
    263         return bt->data;
    264     }
    265     if (bt->lchild && bt->rchild->data == num)
    266     {
    267         return bt->data;
    268     }
    269     getfather(bt->lchild, num);
    270     getfather(bt->rchild, num);
    271 }
    272 
    273 int getleft(BinTNode *bt, int num)//查找二叉树的某个结点的左兄弟
    274 {
    275     if (!bt)
    276     {
    277         return 0;
    278     }
    279     if (bt->rchild && bt->rchild->data == num)
    280     {
    281         if (bt->lchild)
    282         {
    283             return bt->lchild->data;
    284         }
    285     }
    286     getfather(bt->lchild, num);
    287     getfather(bt->rchild, num);
    288 }
    289 
    290 int findmax(BinTNode *bt)//查找二叉树的最大值
    291 {
    292     BinTNode *ST[100];//用指针数组模拟栈
    293     int top = 0;//初始化数组
    294     ST[top] = bt;
    295     int max = 0;//保存最大值
    296 
    297     do
    298     {
    299         while (ST[top] != NULL)//根结点及其所有的左结点地址装入数组
    300         {
    301             top++;
    302             ST[top] = ST[top - 1]->lchild;
    303         }
    304         top = top - 1;
    305         if (top >= 0)//判数组中地址是否访问完
    306         {
    307             if (max < ST[top]->data)
    308             {
    309                 max = ST[top]->data;
    310             }
    311 
    312             ST[top] = ST[top]->rchild;//扫描右子树
    313         }
    314     } while (top != -1);
    315 
    316     return max;
    317 }
    318 
    319 BinTNode *insertnode(BinTNode *bt, int num)//二叉树插入
    320 {
    321     if (!bt)
    322     {
    323         BinTNode *pnew = new BinTNode;
    324         pnew->data = num;
    325         bt = pnew;
    326     }
    327     else if (num < bt->data)
    328     {
    329         bt->lchild = insertnode(bt->lchild, num);
    330     }
    331     else
    332     {
    333         bt->rchild = insertnode(bt->rchild, num);
    334     }
    335 
    336     return bt;
    337 }

    5.3.3二叉树的应用举例

    已知二叉树的前序和中序遍历序列或中序和后序遍历序列,可以还原出原始的二叉树。

    但是已知二叉树的前序和后序遍历序列,是无法还原出原始的二叉树。

    前序遍历,最前面的是根结点。

    后序遍历,最后面的是根结点。

    应用

    树是数据库中数据组织一种重要形式

    操作系统子父进程的关系本身就是一棵树(进程树)

    面向对象语言中类的继承关系本身就是一棵树

    哈夫曼树

  • 相关阅读:
    poj 1087 A Plug for UNIX
    poj 1149 : PIGS
    自己制作的我们学校的校园无线网自动登录程序(C#实现)
    poj 1067取石子(威佐夫博奕)
    poj 1088滑雪
    SQL Server 2005 系统数据介绍:sys.dm_exec_requests
    一票难求:我为铁道部献计献策!
    Integration Services 学习(7):包部署
    Integration Services 学习(8):事务
    Integration Services包部署常见问题汇总
  • 原文地址:https://www.cnblogs.com/denggelin/p/5700882.html
Copyright © 2020-2023  润新知