二叉树的操作 深度广度遍历,二叉树递归和非递归遍历

二叉树的操作

参考:[1]http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html

    [2]http://www.bccn.net/article/kfyy/sjjg/200706/4585.html

[cpp]  view plain  copy
  1. #include"stdio.h"  
  2. #include<iostream>  
  3. #include<stack>  
  4. using namespace std;  
  5. //数据结构  
  6. typedef struct node  
  7. {  
  8.     int value;  
  9.     struct node *lchild;  
  10.     struct node *rchild;  
  11. }BiNode;  
  12. typedef BiNode* BiTree;  
  13.   
  14. typedef struct BTNode{  
  15.         BiNode * btnode;  
  16.         bool isFrist;  
  17. }BTNode;  
  18. //初始化  
  19. void InitBiTree(BiTree *T)  
  20. {  
  21.     *T = NULL;  
  22. }  
  23. //创建  
  24. void CreateBiTree(BiTree *T)  
  25. {  
  26.     int value;   
  27.     printf("输入值:\n");  
  28.     scanf("%d",&value);  
  29.     if(value!= 0)  
  30.     {  
  31.         *T = (BiNode *)malloc(sizeof(BiNode));  
  32.         (*T)->value = value;  
  33.         (*T)->lchild = NULL;  
  34.         (*T)->rchild = NULL;  
  35.         CreateBiTree(&((*T)->lchild));  
  36.         CreateBiTree(&((*T)->rchild));  
  37.     }  
  38.     else  
  39.     {  
  40.         *T = NULL;  
  41.         return;  
  42.     }  
  43. }  
  44. //按层创建  
  45. void CreateBiTreeByLevel(BiTree *T,int *Array,int i,int len)  
  46. {  
  47.     if((Array[i] == 0)|| i > len)return;  
  48.     *T = (BiNode *)malloc(sizeof(BiNode));  
  49.     if(!(*T))exit(0);  
  50.     (*T) ->value = Array[i];  
  51.     (*T)->lchild = NULL;  
  52.     (*T)->rchild = NULL;  
  53.     CreateBiTreeByLevel(&(*T)->lchild,Array,2*i,len);  
  54.     CreateBiTreeByLevel(&(*T)->rchild,Array,2*i+1,len);  
  55. }  
  56. void display(BiTree *t)        //显示树形结构   
  57. {  
  58.     if(*t!=NULL)  
  59.     {  
  60.         cout<<(*t)->value;  
  61.         if((*t)->lchild!=NULL)  
  62.         {  
  63.             cout<<'(';  
  64.             display(&(*t)->lchild);  
  65.         }  
  66.         if((*t)->rchild!=NULL)  
  67.         {  
  68.             cout<<',';  
  69.             display(&(*t)->rchild);  
  70.             cout<<')';  
  71.         }  
  72.     }  
  73. }  
  74. //----------------深度遍历二叉树-------递归的方法-------  
  75. //前序遍历  
  76. void PreOrderTraverse(BiTree *t)  
  77. {  
  78.     if(!(*t))return;  
  79.     printf("%d",(*t)->value);  
  80.     PreOrderTraverse(&((*t)->lchild));  
  81.     PreOrderTraverse(&((*t)->rchild));  
  82. }  
  83. // 后序遍历  
  84. void PostOrderTraverse(BiTree *t)  
  85. {  
  86.     if(!(*t))return;  
  87.     PostOrderTraverse(&((*t)->lchild));  
  88.     PostOrderTraverse(&((*t)->rchild));  
  89.     printf("%d",(*t)->value);  
  90. }  
  91. //中序遍历  
  92. void InOrderTraverse(BiTree *t)  
  93. {  
  94.     if(!(*t))return;  
  95.     InOrderTraverse(&(*t)->lchild);  
  96.     printf("%d",(*t)->value);  
  97.     InOrderTraverse(&(*t)->rchild);    
  98. }  
  99. //-------------------深度遍历二叉树---非递归方法---------------------------  
  100. //非递归前序遍历  
  101. /************************************************************************/  
  102. /* 1)访问节点p,将节点p入栈*/  
  103. /* 2)p左孩子不为空,则一直入栈,当p的左孩子为空时,出栈*/  
  104. /* 3)直到p为空或者栈s为空,遍历结束*/  
  105. /*前序遍历根左右,入栈时访问为谦虚,中序遍历时,左根右,出栈时访问*/  
  106. /************************************************************************/  
  107. void PreOrderTraverse1(BiTree *t)  
  108. {  
  109.     stack <BiTree> s;  
  110.     BiNode *p = *t;  
  111.     while(p!=NULL||!s.empty())  
  112.     {  
  113.         while(p)  
  114.         {  
  115.             printf("%d",p->value);  
  116.             s.push(p);  
  117.             p = p->lchild;  
  118.         }  
  119.         if(!s.empty())  
  120.         {  
  121.             p = s.top();  
  122.             s.pop();  
  123.             p = p->rchild;  
  124.         }  
  125.     }  
  126. }  
  127.   
  128.   
  129. //非递归中序遍历  
  130. void InOrderTraverse1(BiTree *t)  
  131. {  
  132.     stack<BiTree> s;  
  133.     BiNode *p = *t;  
  134.     while(p!=NULL || !s.empty())  
  135.     {  
  136.         while(p)  
  137.         {  
  138.             s.push(p);  
  139.             p = p->lchild;  
  140.         }  
  141.         if(!s.empty())  
  142.         {  
  143.             p = s.top();  
  144.             printf("%d",p->value);  
  145.             s.pop();  
  146.             p = p->rchild;  
  147.         }  
  148.     }  
  149. }   
  150.   
  151.   
  152. //后续非递归遍历  
  153. /* 
  154.  第一种思路:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点, 
  155.  此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同 
  156.  的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。 
  157.  这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现 
  158.  在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。 
  159. */  
  160. void PostOrderTraverse1(BiTree *t)  
  161. {  
  162.     stack<BTNode*> s;  
  163.     BiNode *p = *t;  
  164.     BTNode *temp;  
  165.     while(p!=NULL||!s.empty())  
  166.     {  
  167.         while(p)  
  168.         {  
  169.             BTNode *btn = (BTNode *)malloc(sizeof(BTNode));  
  170.             btn->btnode = p;  
  171.             btn->isFrist = true;  
  172.             s.push(btn);  
  173.             p = p->lchild;  
  174.         }  
  175.         if(!s.empty())  
  176.         {  
  177.             temp = s.top();  
  178.             s.pop();  
  179.             if(temp->isFrist)  
  180.             {  
  181.                 s.push(temp);  
  182.                 temp->isFrist = false;  
  183.                 p = temp->btnode->rchild;  
  184.             }  
  185.             else  
  186.             {  
  187.                 printf("%d",temp->btnode->value);  
  188.                 p = NULL;  
  189.             }  
  190.   
  191.         }  
  192.     }      
  193. }  
  194. /* 
  195. 第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。 
  196. 如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右 
  197. 孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次 
  198. 入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点 
  199. 前面被访问。 
  200. */  
  201. void PostOrderTraverse2(BiTree *t)  
  202. {  
  203.     stack<BiNode*> s;  
  204.     BiNode *pre = NULL;  
  205.     BiNode *cur = NULL;  
  206.     s.push(*t);  
  207.     while(!s.empty())  
  208.     {  
  209.         cur = s.top();  
  210.         if(((cur->lchild == NULL)&&(cur->rchild == NULL))||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))  
  211.         {  
  212.             printf("%d",cur->value);//如果当前结点没有孩子结点或者孩子节点都已被访问过   
  213.             s.pop();                //由于入栈时根右左,pre指向其右或者左节点,   
  214.             pre = cur;  
  215.         }  
  216.         else  
  217.         {  
  218.             if(cur->rchild!=NULL)s.push(cur->rchild);  
  219.             if(cur->lchild!=NULL)s.push(cur->lchild);      
  220.         }  
  221.     }  
  222. }  
  223. //----------------------------------广度遍历二叉树----------使用队列按照层序遍历二叉树-----------------------  
  224. void LevelOrderTranverse(BiTree *t)  
  225. {  
  226.     queue<binode> q;  
  227.     BiNode * p = NULL;  
  228.     if(*t)q.push(*t);  
  229.     else return;  
  230.       
  231.     while(!q.empty())  
  232.     {  
  233.         p = q.front();  
  234.         q.pop();  
  235.         cout<<p->value<<"*";  
  236.         if (p->lchild!=NULL)q.push(p->lchild);  
  237.         if (p->rchild!=NULL)q.push(p->rchild);  
  238.     }  
  239. }  
  240. int main()  
  241. {  
  242.     BiTree T;  
  243.     InitBiTree(&T);  
  244.     int a[14] = {0,1,2,3,4,5,6,0,0,0,7,0,8,9};//从下标1开始,0标识没有节点  
  245.     CreateBiTreeByLevel(&T,a,1,13);  
  246.     display(&T);  
  247.     printf("\n---------PreOrder---------------\n");  
  248.     PreOrderTraverse(&T);  
  249.     printf("\n--------------------------------\n");  
  250.     PreOrderTraverse1(&T);  
  251.     printf("\n---------InOrder-----------------\n");  
  252.     InOrderTraverse(&T);  
  253.     printf("\n------------------------\n");  
  254.     InOrderTraverse1(&T);  
  255.     printf("\n---------PostOrder---------------\n");  
  256.     PostOrderTraverse(&T);  
  257.     printf("\n---------------------------------\n");  
  258.     PostOrderTraverse1(&T);  
  259.     printf("\n---------------------------------\n");  
  260.     PostOrderTraverse2(&T);  
  261.     system("pause");  
  262. }  
  263. </p-></binode>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值