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. }  

构建二叉树示意图为:

 

运行程序结果为:

posted @ 2015-01-16 14:35  温布利往事  阅读(608)  评论(0编辑  收藏  举报