zoukankan      html  css  js  c++  java
  • 遍历二叉树的各种操作

     先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序、中序、后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组队列,分别使用了front和rear两个数组的下标来表示入队与出队,还有两个操作就是求二叉树的深度、结点数。。。

    1. #include "iostream"  
    2. #include "queue"  
    3. #include "stack"  
    4. using namespace std;  
    5.   
    6. //二叉树结点的描述  
    7. typedef struct BiTNode  
    8. {  
    9.     char data;  
    10.     struct BiTNode *lchild, *rchild;      //左右孩子  
    11. }BiTNode,*BiTree;  
    12.   
    13. //按先序遍历创建二叉树  
    14. //BiTree *CreateBiTree()     //返回结点指针类型  
    15. //void CreateBiTree(BiTree &root)      //引用类型的参数  
    16. void CreateBiTree(BiTNode **root)    //二级指针作为函数参数  
    17. {  
    18.     char ch; //要插入的数据  
    19.     scanf("\n%c", &ch);  
    20.     //cin>>ch;  
    21.     if(ch=='#')  
    22.         *root = NULL;  
    23.     else  
    24.     {  
    25.         *root = (BiTNode *)malloc(sizeof(BiTNode));  
    26.         (*root)->data = ch;  
    27.         printf("请输入%c的左孩子:",ch);  
    28.         CreateBiTree(&((*root)->lchild));  
    29.         printf("请输入%c的右孩子:",ch);  
    30.         CreateBiTree(&((*root)->rchild));  
    31.     }  
    32. }  
    33.   
    34. //前序遍历的算法程序  
    35. void PreOrder(BiTNode *root)  
    36. {  
    37.     if(root==NULL)  
    38.         return ;  
    39.     printf("%c ", root->data); //输出数据  
    40.     PreOrder(root->lchild); //递归调用,前序遍历左子树  
    41.     PreOrder(root->rchild); //递归调用,前序遍历右子树  
    42. }  
    43.   
    44. //中序遍历的算法程序  
    45. void InOrder(BiTNode *root)  
    46. {  
    47.     if(root==NULL)  
    48.         return ;  
    49.     InOrder(root->lchild); //递归调用,前序遍历左子树  
    50.     printf("%c ", root->data); //输出数据  
    51.     InOrder(root->rchild); //递归调用,前序遍历右子树  
    52. }  
    53.   
    54. //后序遍历的算法程序  
    55. void PostOrder(BiTNode *root)  
    56. {  
    57.     if(root==NULL)  
    58.         return ;  
    59.     PostOrder(root->lchild); //递归调用,前序遍历左子树  
    60.     PostOrder(root->rchild); //递归调用,前序遍历右子树  
    61.     printf("%c ", root->data); //输出数据    
    62. }  
    63.   
    64. void PreOrder_Nonrecursive(BiTree T)  //先序遍历的非递归  
    65. {  
    66.     stack<BiTree> S;  
    67.     BiTree p;  
    68.     S.push(T);  //根指针进栈  
    69.     while(!S.empty())  //栈空时结束  
    70.     {  
    71.         while((p=S.top()) && p)  
    72.         {  
    73.             cout<<p->data<<"  ";  
    74.             S.push(p->lchild);  
    75.         }   //向左走到尽头  
    76.         S.pop();  //弹出堆栈  
    77.         if(!S.empty())  
    78.         {  
    79.             p=S.top();  
    80.             S.pop();  
    81.             S.push(p->rchild);    //向右走一步  
    82.         }  
    83.     }  
    84. }  
    85. void InOrderTraverse(BiTree T)   //中序遍历的非递归  
    86. {  
    87.     stack<BiTree> S;  
    88.     BiTree p;  
    89.     S.push(T);   //根指针进栈  
    90.     while(!S.empty())  
    91.     {  
    92.         while((p=S.top()) && p)  
    93.             S.push(p->lchild);    //向左走到尽头  
    94.         S.pop();    //空指针退栈  
    95.         if(!S.empty())  
    96.         {  
    97.             p=S.top();  
    98.             S.pop();  
    99.             cout<<p->data<<"  ";  
    100.             S.push(p->rchild);  
    101.         }  
    102.     }  
    103. }  
    104.   
    105. void PostOrder_Nonrecursive(BiTree T)  //后序遍历的非递归  
    106. {  
    107.     stack<BiTree> S;  
    108.     BiTree p=T,q=NULL;  
    109.     while(p!=NULL || !S.empty())  //栈空时结束  
    110.     {  
    111.         while(p!=NULL)  
    112.         {  
    113.             S.push(p);  
    114.             p=p->lchild;  
    115.         }  
    116.         p=S.top();  
    117.         if(p->rchild==NULL || p->rchild==q)  
    118.         {  
    119.             cout<<p->data<<"  ";  
    120.             q=S.top();  
    121.             S.pop();  
    122.             p=NULL;  
    123.         }  
    124.         else   
    125.             p=p->rchild;  
    126.     }  
    127. }  
    128. int visit(BiTree T)  
    129. {  
    130.     if(T)  
    131.     {  
    132.         printf("%c ",T->data);  
    133.         return 1;  
    134.     }  
    135.     else  
    136.         return 0;  
    137. }  
    138.   
    139. void LeverTraverse(BiTree T)   //方法一、非递归层次遍历二叉树   
    140. {  
    141.     queue <BiTree> Q;  
    142.     BiTree p;  
    143.     p = T;  
    144.     if(visit(p)==1)  
    145.         Q.push(p);  
    146.     while(!Q.empty())  
    147.     {  
    148.         p = Q.front();  
    149.         Q.pop();  
    150.         if(visit(p->lchild) == 1)   
    151.             Q.push(p->lchild);  
    152.         if(visit(p->rchild) == 1)  
    153.             Q.push(p->rchild);  
    154.     }  
    155. }  
    156. void LevelOrder(BiTree BT)     //方法二、非递归层次遍历二叉树   
    157. {  
    158.     BiTNode *queue[10];//定义队列有十个空间  
    159.     if (BT==NULL)  
    160.         return;  
    161.     int front,rear;  
    162.     front=rear=0;  
    163.     queue[rear++]=BT;  
    164.     while(front!=rear)//如果队尾指针不等于对头指针时  
    165.     {  
    166.         cout<<queue[front]->data<<"  ";  //输出遍历结果  
    167.         if(queue[front]->lchild!=NULL)  //将队首结点的左孩子指针入队列  
    168.         {  
    169.             queue[rear]=queue[front]->lchild;  
    170.             rear++;    //队尾指针后移一位  
    171.         }  
    172.         if(queue[front]->rchild!=NULL)  
    173.         {  
    174.             queue[rear]=queue[front]->rchild;    //将队首结点的右孩子指针入队列  
    175.             rear++;   //队尾指针后移一位  
    176.         }  
    177.         front++;    //对头指针后移一位  
    178.     }  
    179. }  
    180.   
    181. int depth(BiTNode *T)   //树的深度  
    182. {  
    183.     if(!T)  
    184.         return 0;  
    185.     int d1,d2;  
    186.     d1=depth(T->lchild);  
    187.     d2=depth(T->rchild);  
    188.     return (d1>d2?d1:d2)+1;  
    189.     //return (depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1;  
    190. }  
    191. int CountNode(BiTNode *T)  
    192. {  
    193.     if(T == NULL)  
    194.         return 0;  
    195.     return 1+CountNode(T->lchild)+CountNode(T->rchild);  
    196. }  
    197.   
    198. int main(void)  
    199. {  
    200.     BiTNode *root=NULL; //定义一个根结点  
    201.     int flag=1,k;  
    202.     printf("                     本程序实现二叉树的基本操作。\n");  
    203.     printf("可以进行建立二叉树,递归先序、中序、后序遍历,非递归先序、中序遍历及非递归层序遍历等操作。\n");  
    204.   
    205.     while(flag)  
    206.     {  
    207.         printf("\n");  
    208.         printf("|--------------------------------------------------------------|\n");  
    209.         printf("|                    二叉树的基本操作如下:                     |\n");  
    210.         printf("|                        0.创建二叉树                          |\n");  
    211.         printf("|                        1.递归先序遍历                        |\n");  
    212.         printf("|                        2.递归中序遍历                        |\n");  
    213.         printf("|                        3.递归后序遍历                        |\n");  
    214.         printf("|                        4.非递归先序遍历                      |\n");  
    215.         printf("|                        5.非递归中序遍历                      |\n");  
    216.         printf("|                        6.非递归后序遍历                      |\n");  
    217.         printf("|                        7.非递归层序遍历                      |\n");  
    218.         printf("|                        8.二叉树的深度                        |\n");  
    219.         printf("|                        9.二叉树的结点个数                    |\n");  
    220.         printf("|                        10.退出程序                            |\n");  
    221.         printf("|--------------------------------------------------------------|\n");  
    222.         printf("                        请选择功能:");  
    223.         scanf("%d",&k);  
    224.         switch(k)  
    225.         {  
    226.         case 0:  
    227.             printf("请建立二叉树并输入二叉树的根节点:");  
    228.             CreateBiTree(&root);  
    229.             break;  
    230.         case 1:  
    231.             if(root)  
    232.             {  
    233.                 printf("递归先序遍历二叉树的结果为:");  
    234.                 PreOrder(root);  
    235.                 printf("\n");  
    236.             }  
    237.             else  
    238.                 printf("          二叉树为空!\n");  
    239.             break;  
    240.         case 2:  
    241.             if(root)  
    242.             {  
    243.                 printf("递归中序遍历二叉树的结果为:");  
    244.                 InOrder(root);  
    245.                 printf("\n");  
    246.             }  
    247.             else  
    248.                 printf("          二叉树为空!\n");  
    249.             break;  
    250.         case 3:  
    251.             if(root)  
    252.             {  
    253.                 printf("递归后序遍历二叉树的结果为:");  
    254.                 PostOrder(root);  
    255.                 printf("\n");  
    256.             }  
    257.             else  
    258.                 printf("          二叉树为空!\n");  
    259.             break;  
    260.         case 4:  
    261.             if(root)  
    262.             {  
    263.                 printf("非递归先序遍历二叉树:");  
    264.                 PreOrder_Nonrecursive(root);  
    265.                 printf("\n");  
    266.             }  
    267.             else  
    268.                 printf("          二叉树为空!\n");  
    269.             break;  
    270.         case 5:  
    271.             if(root)  
    272.             {  
    273.                 printf("非递归中序遍历二叉树:");  
    274.                 InOrderTraverse(root);  
    275.                 printf("\n");  
    276.             }  
    277.             else  
    278.                 printf("          二叉树为空!\n");  
    279.             break;  
    280.         case 6:  
    281.             if(root)  
    282.             {  
    283.                 printf("非递归后序遍历二叉树:");  
    284.                 PostOrder_Nonrecursive(root);  
    285.                 printf("\n");  
    286.             }  
    287.             else  
    288.                 printf("          二叉树为空!\n");  
    289.             break;  
    290.         case 7:  
    291.             if(root)  
    292.             {  
    293.                 printf("非递归层序遍历二叉树:");  
    294.                 //LeverTraverse(root);  
    295.                 LevelOrder(root);  
    296.                 printf("\n");  
    297.             }  
    298.             else  
    299.                 printf("          二叉树为空!\n");  
    300.             break;  
    301.         case 8:  
    302.             if(root)  
    303.                 printf("这棵二叉树的深度为:%d\n",depth(root));  
    304.             else  
    305.                 printf("          二叉树为空!\n");  
    306.             break;  
    307.         case 9:  
    308.             if(root)  
    309.                 printf("这棵二叉树的结点个数为:%d\n",CountNode(root));  
    310.             else  
    311.                 printf("          二叉树为空!\n");  
    312.             break;  
    313.         default:  
    314.             flag=0;  
    315.             printf("程序运行结束,按任意键退出!\n");  
    316.         }  
    317.     }  
    318.     system("pause");  
    319.     return 0;  
    320. }  

    运行效果图如下:

    分别输入:

    1

    2

    4

    #

    #

    5

    #

    #

    3

    6

    #

    #

    7

    #

    就可以构造如下图所示的二叉树了。。

    后序遍历非递归的另外一种写法:

    1. /* 
    2. 后序遍历由于遍历父节点是在遍历子节点之后,而且左节点和右节点遍历后的行为不一样, 
    3. 所以需要用变量来记录前一次访问的节点,根据前一次节点和现在的节点的关系来确定具体执行什么操作 
    4. */  
    5. void Postorder(BiTree T)  
    6. {  
    7.     if(T == NULL)  
    8.         return ;  
    9.     stack<BiTree> s;  
    10.     BiTree prev = NULL , curr = NULL;  
    11.     s.push(T);  
    12.     while(!s.empty())  
    13.     {  
    14.         curr = s.top();  
    15.         if(prev == NULL  || prev->lchild == curr || prev->rchild == curr)  
    16.         {  
    17.             if(curr->lchild != NULL)  
    18.                 s.push(curr->lchild);  
    19.             else if(curr->rchild != NULL)  
    20.                 s.push(curr->rchild);  
    21.         }  
    22.         else if(curr->lchild == prev)  
    23.         {  
    24.             if(curr->rchild != NULL)  
    25.                 s.push(curr->rchild);  
    26.         }  
    27.         else  
    28.         {  
    29.             cout<<curr->data;  
    30.             s.pop();  
    31.         }  
    32.         prev = curr;  
    33.     }  
    34. }  

    输入二叉树中的两个节点,输出这两个结点在数中最低的共同父节点。
    思路:遍历二叉树,找到一条从根节点开始到目的节点的路径,然后在两条路径上查找共同的父节点。

      1. // 得到一条从根节点开始到目的节点的路径  
      2. bool GetNodePath(TreeNode *pRoot , TreeNode *pNode , vector<TreeNode *> &path)  
      3. {  
      4.     if(pRoot == NULL)  
      5.         return false;  
      6.     if(pRoot == pNode)  
      7.         return true;  
      8.     else if(GetNodePath(pRoot->lchild , pNode , path) )  
      9.     {  
      10.         path.push_back(pRoot->lchild);  
      11.         return true;  
      12.     }  
      13.     else if(GetNodePath(pRoot->rchild , pNode , path) )  
      14.     {  
      15.         path.push_back(pRoot->rchild);  
      16.         return true;  
      17.     }  
      18.     return false;  
      19. }  
      20. TreeNode *GetLastCommonNode(const vector<TreeNode *> &path1 , const vector<TreeNode *> &path2)  
      21. {  
      22.     vector<TreeNode *>::const_iterator iter1 = path1.begin();  
      23.     vector<TreeNode *>::const_iterator iter2 = path2.begin();  
      24.     TreeNode *pLast;  
      25.     while(iter1 != path1.end() && iter2 != path2.end() )  
      26.     {  
      27.         if(*iter1 == *iter2)  
      28.             pLast = *iter1;  
      29.         else  
      30.             break;  
      31.         iter1++;  
      32.         iter2++;  
      33.     }  
      34.     return pLast;  
      35. }  
      36. TreeNode *GetLastCommonParent(TreeNode *pRoot , TreeNode *pNode1 , TreeNode *pNode2)  
      37. {  
      38.     if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)  
      39.         return  NULL;  
      40.     vector<TreeNode *> path1;  
      41.     GetNodePath(pRoot , pNode1 , path1);  
      42.   
      43.     vector<TreeNode *> path2;  
      44.     GetNodePath(pRoot , pNode2 , path2);  
      45.     return GetLastCommonNode(path1 , path2);  
      46. }  

    原文转自:http://blog.csdn.net/hackbuteer1/article/details/6583988

  • 相关阅读:
    Shell Script-读取配置文件
    [LeetCode]题解(python):048-Rotate Image
    [LeetCode]题解(python):043-Multiply Strings
    暑假学习记录(七)
    暑期学习记录(六)
    暑假学习记录(五)
    暑假学习记录(四)
    暑假学习记录(三)
    暑假学习记录(二)
    暑假学习记录(一)
  • 原文地址:https://www.cnblogs.com/10jschen/p/2679577.html
Copyright © 2011-2022 走看看