二叉树----节点个数、高度、递归和非递归遍历、按层遍历

转自:http://blog.csdn.net/dazhong159/article/details/7862774

1、二叉树的数据结构(数据域+指向左/右孩子节点的指针)

    typedef struct tree
    {
         int data;
         struct tree *left;
         struct tree *right;
    }Tree,*pTree;

2、创建二叉查找树

[html]  view plain copy
  1. //创建二叉树(二叉查找树),返回根节点  
  2. pTree createTree(int *data,int len)  
  3. {  
  4.     if (len<1)  
  5.     {  
  6.         cout<<"创建的树为空树!"<<endl;  
  7.         return NULL;  
  8.     }  
  9.     pTree root=(pTree)malloc(sizeof(Tree));  
  10.     root->data=data[0];  
  11.     root->left=NULL;  
  12.     root->right=NULL;  
  13.   
  14.   
  15.     pTree current,back;  
  16.     for (int i=1;i<len;i++)  
  17.     {  
  18.         pTree newNode=(pTree)malloc(sizeof(Tree));  
  19.         newNode->data=data[i];  
  20.         newNode->left=NULL;  
  21.         newNode->right=NULL;  
  22.   
  23.         current=root;//每次插入新的节点时,current都指向root  
  24.         while(current!=NULL)  
  25.         {  
  26.             back=current;  
  27.             if (current->data>data[i])  
  28.                 current=current->left;  
  29.             else  
  30.                 current=current->right;  
  31.         }  
  32.   
  33.         if(back->data>data[i])  
  34.             back->left=newNode;  
  35.         else  
  36.             back->right=newNode;  
  37.     }  
  38.   
  39.     return root;  
  40. }  

3、二叉树节点个数(递归法)

[html]  view plain copy
  1. //递归求树的节点个数(左子树节点个数+右子树节点个数+根节点个数)  
  2. int getNode(pTree root)  
  3. {  
  4.     if (root==NULL)  
  5.         return 0;  
  6.     else if (root->left==NULL&&root->right==NULL)  
  7.         return 1;  
  8.     else  
  9.         return getNode(root->left)+getNode(root->right)+1;  
  10. }  

4、二叉树的高度(递归法)

[html]  view plain copy
  1. //递归求树的高度(左子树和右子树高度中的较大的值+根节点高度1)  
  2. int getHeight(pTree root)  
  3. {  
  4.     if (root==NULL)  
  5.         return 0;  
  6.       
  7.     int lh=getHeight(root->left);  
  8.     int rh=getHeight(root->right);  
  9.       
  10.     return lh>rh ? lh+1:rh+1;  
  11. }  

5、递归遍历二叉树

[html]  view plain copy
  1. //递归进行前序遍历  
  2. void preTraverse(pTree root)  
  3. {  
  4.     if (root!=NULL)  
  5.     {  
  6.         cout<<root->data<<" ";  
  7.         preTraverse(root->left);  
  8.         preTraverse(root->right);  
  9.     }  
  10. }  
  11.   
  12. //递归进行中序遍历  
  13. void midTraverse(pTree root)  
  14. {  
  15.     if (root!=NULL)  
  16.     {  
  17.         midTraverse(root->left);  
  18.         cout<<root->data<<" ";  
  19.         midTraverse(root->right);  
  20.     }  
  21. }  
  22.   
  23. //递归进行后序遍历  
  24. void postTraverse(pTree root)  
  25. {  
  26.     if (root!=NULL)  
  27.     {  
  28.         postTraverse(root->left);  
  29.         postTraverse(root->right);  
  30.         cout<<root->data<<" ";  
  31.     }  
  32. }  

6、非递归遍历二叉树

[html]  view plain copy
  1. /**************************************************************************  
  2.  * 利用栈进行前序遍历  
  3.  * 1、从根节点开始,遍历左子树,输出父节点的内容,并将父节点入栈(这里用数组代替)  
  4.  * 2、遍历遇到节点为NULL时,取出栈顶元素,得到其右孩子节点  
  5.  * 3、右孩子节点不为空时,此时将该右节点看作是根节点,重复1、2操作  
  6.  * 4、右孩子节点为空时,继续出栈,得到右孩子节点,重复3、4操作  
  7. **************************************************************************/  
  8. void prePrint(pTree root)  
  9. {  
  10.     pTree p=root;  
  11.     int height=getHeight(root);  
  12.     pTree *sk=new pTree[height+1];  
  13.     int cnt=0;  
  14.     while(p!=NULL||cnt!=0)  
  15.     {  
  16.         if (p!=NULL)    
  17.         {  
  18.             cout<<p->data<<" ";  
  19.             sk[cnt++]=p;  
  20.             p=p->left;  
  21.         }   
  22.         else  
  23.         {  
  24.             p=sk[--cnt];  
  25.             p=p->right;  
  26.         }  
  27.     }  
  28.     delete []sk;  
  29. }  
  30.   
  31. /****************************************************************************  
  32.  * 利用栈进行中序遍历  
  33.  * 1、从根节点开始,遍历左子树,将父节点入栈(这里用数组代替)  
  34.  * 2、遍历遇到节点为NULL时,取出栈顶元素,输出节点内容,得到其右孩子节点  
  35.  * 3、右孩子节点不为空时,此时将该右节点看作是根节点,重复1、2操作  
  36.  * 4、右孩子节点为空时,继续出栈,重复3、4操作  
  37. ****************************************************************************/  
  38. void midPrint(pTree root)  
  39. {  
  40.     pTree p=root;  
  41.     int height=getHeight(root);  
  42.     pTree *sk=new pTree[height+1];  
  43.     int cnt=0;  
  44.     while(p!=NULL||cnt!=0)  
  45.     {  
  46.         if (p!=NULL)  
  47.         {  
  48.             sk[cnt++]=p;  
  49.             p=p->left;  
  50.         }  
  51.         else  
  52.         {  
  53.             p=sk[--cnt];  
  54.             cout<<p->data<<" ";  
  55.             p=p->right;  
  56.         }  
  57.     }  
  58.     delete []sk;  
  59. }  
  60.   
  61. /**********************************************************************  
  62.  * 利用栈后序遍历  
  63.  * 1、首先创建一种新的数据结构,包含原来的数据结构和isFirst标志()  
  64.  * 2、从根节点开始,入栈,将isFirst置为1,访问左子树  
  65.  * 3、遇到节点为NULL时,如果isFirst==1,访问栈顶元素,得到该节点的右孩子  
  66.  * 4、该节点的右孩子为NULL时,出栈,访问该节点,然后将该节点置为NULL,使下次循环必定会进入第3步  
  67.  * 5、该节点的右孩子不为NULL时,将该右孩子当作根节点,重复2、3  
  68. **********************************************************************/  
  69. void postPrint(pTree root)  
  70. {  
  71.     int height=getHeight(root);  
  72.     struct TPostTree    //节点新的数据结构  
  73.     {  
  74.         pTree node;  
  75.         int isFirst;  
  76.     };  
  77.     TPostTree *sk=new TPostTree[height+1];  
  78.     int cnt=0;  
  79.   
  80.     pTree p=root;  
  81.     while(p!=NULL||cnt!=0)  
  82.     {  
  83.         if (p!=NULL)  //左  
  84.         {  
  85.             sk[++cnt].node=p;  
  86.             sk[cnt].isFirst=1;  
  87.             p=p->left;  
  88.         }  
  89.         else if (sk[cnt].isFirst)   //右  
  90.         {  
  91.             sk[cnt].isFirst=0;  
  92.             p=sk[cnt].node->right;  //根据sk保存的找到右节点  
  93.         }   
  94.         else        //根节点  
  95.         {  
  96.             p=sk[cnt--].node;  
  97.             cout<<p->data<<" ";  
  98.             p=NULL;                 //保证下次循环必定进入if的else分支  
  99.         }  
  100.     }  
  101.     delete []sk;  
  102. }  

7、按层遍历二叉树

[html]  view plain copy
  1. /***************************************************************************  
  2.  * 按层遍历  
  3.  * 1、访问根节点,将根节点进队  
  4.  * 2、取出队列的第一个元素,访问该元素,并将取出的该元素节点的左右孩子节点(不为NULL)进队  
  5.  * 3、循环进行第二步,直至队列为空  
  6.  * 4、下面的代码用数组替换了队列  
  7. ***************************************************************************/  
  8. void BTraverse(pTree root)  
  9. {  
  10.     int n=getNode(root);  
  11.     pTree *sk=new pTree[n],p;  
  12.     int front=0,rear=0;  
  13.     sk[front]=root;  
  14.     while(front!=n)  
  15.     {  
  16.         p=sk[front];  
  17.         cout<<p->data<<" ";  
  18.         if (p->left!=NULL)  
  19.         {  
  20.             sk[rear+1]=p->left;  
  21.             rear++;  
  22.         }  
  23.         if (p->right!=NULL)  
  24.         {  
  25.             sk[rear+1]=p->right;  
  26.             rear++;  
  27.         }  
  28.         front++;  
  29.     }  
  30.   
  31.     cout<<endl;  
  32.     delete []sk;  

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值