• c++学习笔记—二叉树基本操作的实现


    用c++语言实现的二叉树基本操作,包括二叉树的创建、二叉树的遍历(包括前序、中序、后序递归和非递归算法)、求二叉树高度,计数叶子节点数、计数度为1的节点数等基本操作。

    IDE:vs2013

    具体实现代码如下:

    [cpp] view plaincopy
     
    1. #include "stdafx.h"  
    2. #include <malloc.h>  
    3. #include <stack>  
    4. #include <iostream>  
    5. #define MAXSIZE 100   
    6. using namespace std;  
    7. typedef struct node   //二叉树结构体  
    8. {  
    9.     int data;  
    10.     struct node *lchild;  
    11.     struct node *rchild;  
    12. }Bnode,*BTree;  
    13.   
    14. BTree CreateBinaryTree(BTree &tree){            //创建二叉树  
    15.     int inputdata;  
    16.     cin >> inputdata;  
    17.     if (-1 == inputdata)  
    18.     {  
    19.         tree = NULL;  
    20.     }  
    21.     else  
    22.     {  
    23.         if (!(tree = (Bnode*)malloc(sizeof(Bnode))))  
    24.         {  
    25.             cout<<"ERROR";  
    26.         }  
    27.         tree->data = inputdata;  
    28.         tree->lchild=CreateBinaryTree(tree->lchild);  
    29.         tree->rchild=CreateBinaryTree(tree->rchild);  
    30.     }  
    31.     return tree;  
    32. }  
    33. void preorderTraverse(BTree tree)    //递归前序遍历  
    34. {  
    35.     if (tree != NULL)  
    36.     {  
    37.         cout<<tree->data;  
    38.     }  
    39.     if (tree->lchild != NULL)  
    40.     {  
    41.         preorderTraverse(tree->lchild);  
    42.     }  
    43.     if (tree->rchild)  
    44.     {  
    45.         preorderTraverse(tree->rchild);  
    46.     }  
    47. }  
    48.   
    49. void preorderTraverse2(BTree tree)     
    50. {  
    51.   
    52.     //////////////////////////////////////////////////////////////////////////  
    53.     //          非递归前序                         
    54.     //    根据前序遍历访问的顺序,优先访问根结点,                
    55.     //    然后再分别访问左孩子和右孩子。                         
    56.     //    即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,    
    57.     //    若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,      
    58.     //    再访问它的右子树。因此其处理过程如下:                 
    59.     //                                    
    60.     //////////////////////////////////////////////////////////////////////////  
    61.     stack<BTree> s;  
    62.     if (!tree)  
    63.     {  
    64.         cout << "空树" << endl;  
    65.         return;  
    66.     }  
    67.     while (tree || !s.empty())  
    68.     {  
    69.         while (tree)  
    70.         {  
    71.             s.push(tree);  
    72.             cout << tree->data;  
    73.             tree = tree->lchild;  
    74.         }  
    75.         tree = s.top();  
    76.         s.pop();  
    77.         tree = tree->rchild;  
    78.     }  
    79. }  
    80.   
    81. void inorderTraverse(BTree tree)      //递归中序遍历  
    82. {  
    83.     if (tree->lchild)  
    84.     {  
    85.         inorderTraverse(tree->lchild);  
    86.     }  
    87.     cout << tree->data;  
    88.     if (tree->rchild)  
    89.     {  
    90.         inorderTraverse(tree->rchild);  
    91.     }  
    92. }  
    93. void inorderTraverse2(BTree tree)       
    94. {  
    95.      //////////////////////////////////////////////////////////////////////////  
    96.      //            非递归中序遍历                    
    97.          //      根据中序遍历的顺序,对于任一结点,优先访问其左孩子,               
    98.          //      而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,    
    99.         //       直到遇到左孩子结点为空的结点才进行访问,                  
    100.         //       然后按相同的规则访问其右子树。                       
    101.         //       因此其处理过程如下:               
    102.         //                                    
    103.     ///////////////////////////////////////////////////////////////////////////  
    104.     stack<BTree> s;  
    105.     if (!tree)  
    106.     {  
    107.         cout << "空树" << endl;  
    108.         return;  
    109.     }  
    110.     while (tree || !s.empty())  
    111.     {  
    112.         while (tree)  
    113.         {  
    114.             s.push(tree);  
    115.             tree = tree->lchild;  
    116.         }  
    117.         tree = s.top();  
    118.         s.pop();  
    119.         cout << tree->data;  
    120.         tree = tree->rchild;  
    121.     }  
    122. }  
    123. void postoderTraverse(BTree tree)     //递归后序遍历  
    124. {  
    125.     if (tree->lchild)  
    126.     {  
    127.         postoderTraverse(tree->lchild);  
    128.     }  
    129.     if (tree->rchild)  
    130.     {  
    131.         postoderTraverse(tree->rchild);  
    132.     }  
    133.     cout << tree->data;  
    134. }  
    135.   
    136. void postoderTraverse2(BTree tree)            
    137. {  
    138.     //////////////////////////////////////////////////////////////////////////  
    139.     //          非递归后序遍历       
    140.     //      要保证根结点在左孩子和右孩子访问之后才能访问,           
    141.     //  因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,  
    142.     //  则可以直接访问它;或者P存在左孩子或者右孩子,           
    143.     //  但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。    
    144.     //  若非上述两种情况,则将P的右孩子和左孩子依次入栈,         
    145.     //  这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,    
    146.     //  左孩子和右孩子都在根结点前面被访问。                
    147.     //////////////////////////////////////////////////////////////////////////  
    148.   
    149.     stack<BTree> s;  
    150.     BTree cur;                        //当前结点   
    151.     BTree pre = NULL;                 //前一次访问的结点   
    152.     s.push(tree);  
    153.     while (!s.empty())  
    154.     {  
    155.         cur = s.top();  
    156.         if ((cur->lchild == NULL&&cur->rchild == NULL) ||(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))  
    157.                 {  
    158.                     cout << cur->data;  //如果当前结点没有孩子结点或者孩子节点都已被访问过   
    159.                     s.pop();  
    160.                     pre = cur;  
    161.                 }  
    162.         else  
    163.         {  
    164.             if (cur->rchild != NULL)  
    165.                 s.push(cur->rchild);  
    166.             if (cur->lchild != NULL)  
    167.                 s.push(cur->lchild);  
    168.         }  
    169.     }  
    170. }  
    171. int Depth(BTree T)   //求二叉树的深度  
    172. {  
    173.     int dep = 0, depl, depr;  
    174.     if (!T) dep = 0;  
    175.     else  
    176.     {  
    177.         depl = Depth(T->lchild);  
    178.         depr = Depth(T->rchild);  
    179.         dep = 1 + (depl>depr ? depl : depr);  
    180.     }  
    181.     return dep;  
    182. }  
    183. int sumLeaf(BTree tree)   //求叶子节点的个数  
    184. {                           
    185.     int sum = 0, m, n;  
    186.     if (tree)  
    187.     {  
    188.         if ((!tree->lchild) && (!tree->rchild))  
    189.             sum++;  
    190.         m = sumLeaf(tree->lchild);  
    191.         sum += m;  
    192.         n = sumLeaf(tree->rchild);  
    193.         sum += n;  
    194.     }  
    195.     return sum;  
    196. }  
    197. int numnSinglePoint(BTree tree )    //统计度为1的节点数目  
    198. {  
    199.     int sum = 0, m, n;  
    200.     if (tree)  
    201.     {  
    202.         if ((tree->lchild!=NULL) && (tree->rchild == NULL))  
    203.             sum++;  
    204.         if ((tree->lchild == NULL) && (tree->rchild != NULL))  
    205.             sum++;  
    206.         m = numnSinglePoint(tree->lchild);  
    207.             sum += m;  
    208.         n = m = numnSinglePoint(tree->rchild);  
    209.             sum += n;  
    210.     }  
    211.     return sum;  
    212. }  
    213.   
    214. int _tmain(int argc, _TCHAR* argv[])  
    215. {  
    216.     BTree t;  
    217.     t= CreateBinaryTree(t);  
    218.     cout<<endl<<"非递归前序遍历:";  
    219.     preorderTraverse2(t);  
    220.     cout << endl<<"----------------------"<<endl;  
    221.     cout << "递归前序遍历:";  
    222.     preorderTraverse(t);  
    223.     cout << endl << "---------------------"<<endl;  
    224.     cout << "非递归中序遍历:";  
    225.     inorderTraverse2(t);  
    226.     cout << endl << "---------------------"<<endl;  
    227.     cout << "递归中序遍历:";  
    228.     inorderTraverse(t);  
    229.     cout << endl << "---------------------"<<endl;  
    230.     cout << "非递归后序遍历:";  
    231.     postoderTraverse2(t);  
    232.     cout << endl << "---------------------"<<endl;  
    233.     cout << "递归后序遍历:";  
    234.     postoderTraverse(t);  
    235.     cout << endl << "----------------------"<<endl;  
    236.     cout << "链表深度为:"<<Depth(t);  
    237.     cout << endl << "----------------------"<<endl;  
    238.     cout << "链表的叶子节点个数为:" << sumLeaf(t);  
    239.     cout << endl << "----------------------"<<endl;  
    240.     cout << "链表中度为1的节点数目为:" << numnSinglePoint(t) << endl;  
    241.     return 0;  
    242. }  

    构建二叉树示意图为:

     

    运行程序结果为:

  • 相关阅读:
    第二阶段站立会议03
    第二阶段站立会议02
    第二阶段站立会议01
    第十一周进度条
    小强大扫荡
    测试计划
    用户体验
    各组意见
    第一阶段绩效评估
    站立会议10
  • 原文地址:https://www.cnblogs.com/xujian2014/p/4228668.html
Copyright © 2020-2023  润新知