• 二叉树的先序,中序,后序、层级的递归和非递归遍历和获取叶子节点和树的高度


    代码中的二叉树的构造参考了

    http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html

    代码的思想和图片的来源:好大学慕课浙江大学陈越、何钦铭的《数据结构》

    话不多说,直接上代码

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include <ctype.h>
      5 
      6 //efine binary tree element type
      7 typedef char elementType;
      8 
      9 //define binary tree
     10 typedef struct node{
     11     elementType element;
     12     struct node *left;
     13     struct node *right;
     14     int flag;//为了进行非递归的后序遍历,设置入栈标志位,0表示第一次压栈、弹栈,1表示第二此压栈,弹栈
     15 }bTree,*pBinTree;
     16 
     17 
     18 //define the stack element type
     19 typedef pBinTree dataType;
     20 
     21 
     22 //define a stack to store binary tyoe
     23 typedef struct node2{
     24     dataType element;
     25     struct node2 *next;
     26 }sta,*pStack;
     27 
     28 
     29 /*=======================对树栈的操作==============================*/
     30 pStack createEmptyStack(){
     31     pStack stack = (pStack)malloc(sizeof(sta));
     32     if(stack){
     33         stack->next=NULL;
     34     }
     35 }
     36 
     37 int isStackEmpty(pStack stack){
     38     return(stack->next==NULL);
     39 }
     40 
     41 void push(pStack stack,dataType element){
     42     pStack newNode = (pStack)malloc(sizeof(sta));
     43     newNode->element = element;
     44     newNode->next = stack->next;
     45     stack->next = newNode;
     46 }
     47 
     48 dataType pop(pStack stack){
     49     if(isStackEmpty(stack)){
     50         printf("the stack has been empty
    ");
     51         return NULL;
     52     }
     53     pStack temp = stack->next;
     54     stack->next = temp->next;
     55     return temp->element;
     56 }
     57 
     58 int getStackSize(pStack stack){
     59     pStack p = stack->next;
     60     int size=0;
     61     while(p){
     62         size++;
     63         p=p->next;
     64     }
     65     return size;
     66 }
     67 
     68 
     69 
     70 dataType getTop(pStack stack){
     71     if(isStackEmpty(stack)){
     72         printf("the stack has been empty
    ");
     73         return NULL;
     74     }
     75     return (stack->next->element);
     76 }
     77 
     78 //定义一个字符型栈
     79 typedef struct node3{
     80     elementType element;
     81     struct node3 *next;
     82 }charSta,*pCharStack;
     83 
     84 /*====================================对字符栈的操作========================================*/
     85 pCharStack createEmptyCharStack(){
     86     pCharStack stack = (pCharStack)malloc(sizeof(charSta));
     87     if(stack){
     88         stack->next=NULL;
     89     }
     90     return stack;
     91 }
     92 
     93 int isCharStackEmpty(pCharStack stack){
     94     return(stack->next==NULL);
     95 }
     96 
     97 void pushCharStack(pCharStack stack,char ch){
     98     pCharStack newNode = (pCharStack)malloc(sizeof(charSta));
     99     newNode->element = ch;
    100     newNode->next = stack->next;
    101     stack->next=newNode;
    102 }
    103 
    104 
    105 elementType popCharStack(pCharStack stack){
    106     if(isCharStackEmpty(stack)){
    107         return;
    108     }
    109     pCharStack temp=stack->next;
    110     stack->next=temp->next;
    111     return temp->element;
    112 }
    113 
    114 /*============================为了对二叉树进行层次遍历,定义一个链式队列存放二叉树=================================*/
    115 
    116 //定义存放队列元素(二叉树)的链表
    117 typedef struct node4{
    118     dataType element;
    119     struct node4 *next;
    120 }lis,*pList;
    121 
    122 //定义队列的链式存储
    123 typedef struct node5{
    124     struct node4 *font;//指向队列的头指针
    125     struct node4 *rear;//指向队列尾的尾指针
    126 }que,*pQueue;
    127 
    128 pList createEmptyList(){
    129     pList list = (pList)malloc(sizeof(lis));
    130     if(list){
    131         list->next=NULL;
    132     }
    133     return list;
    134 }
    135 
    136 pQueue createEmptyQueue(){
    137     pQueue queue = (pQueue)malloc(sizeof(que));
    138     if(queue){
    139         queue->font=NULL;
    140         queue->rear=NULL;
    141     }
    142 }
    143 
    144 int isQueueEmpty(pQueue queue){
    145     return (queue->font==NULL);
    146 }
    147 
    148 
    149 void addQueue(pQueue queue,dataType element){
    150     if(isQueueEmpty(queue)){
    151         pList list = createEmptyList();
    152         list->element=element;
    153         queue->font=list;
    154         queue->rear=list;
    155     }else{
    156         pList list = (pList)malloc(sizeof(lis));
    157         list->element=element;
    158         list->next = queue->rear->next;
    159         queue->rear->next=list;
    160         queue->rear=list;
    161     }
    162 }
    163 
    164 dataType deleteQueue(pQueue queue){
    165     if(isQueueEmpty(queue)){
    166         return;
    167     }
    168     dataType element = queue->font->element;
    169     if(queue->font==queue->rear){
    170         queue->font=queue->rear=NULL;
    171     }else{
    172         queue->font = queue->font->next;
    173     }
    174     return element;
    175 }
    176 
    177 
    178 /*==========================二叉树的构造和遍历==================================*/
    179 /*
    180 构造一棵二叉树,
    181 s为存储二叉树的元素的字符数组,s为形如A(B,C(D,E))形式的字符串
    182 tree为二叉树创建好的根节点,但是元素为空
    183 */
    184 pBinTree createBinTree(char *s){
    185     int i,isRight;
    186     pStack treeStack = createEmptyStack();//存放节点
    187     pCharStack charStack = createEmptyCharStack();//存放分隔符
    188     pBinTree root = (pBinTree)malloc(sizeof(bTree));
    189     pBinTree temp,p;
    190     root->element=s[0];
    191     root->left=NULL;
    192     root->right=NULL;
    193     push(treeStack,root);
    194     i=1;
    195     while(i<strlen(s)){
    196         if(s[i]=='('){
    197             pushCharStack(charStack,s[i]);
    198             isRight=0;
    199         }else if(s[i]==','){
    200             isRight=1;
    201         }else if(s[i]==')'){
    202             pop(treeStack);
    203             popCharStack(charStack);
    204         }else if(isalpha(s[i])){
    205             p=(pBinTree)malloc(sizeof(bTree));
    206             p->element=s[i];
    207             p->left=NULL;
    208             p->right=NULL;
    209             temp=getTop(treeStack);
    210             //printf("%c %c
    ",s[i],s[i+1]);
    211             if(isRight==1){
    212                 temp->right=p;
    213             }else{
    214                 temp->left=p;
    215             }
    216 
    217             if(s[i+1]=='('){
    218                 push(treeStack,p);
    219             }
    220         }
    221         i++;
    222     }
    223     return root;
    224 }
    225 
    226 //先序遍历
    227 void preOrderTraversal(pBinTree tree){
    228     if(tree){
    229         printf("%c ",tree->element);
    230         preOrderTraversal(tree->left);
    231         preOrderTraversal(tree->right);
    232     }
    233 }
    234 
    235 //先序遍历的非递归方法
    236 void preOrderTraversalStack(pBinTree tree){
    237     pBinTree t = tree;
    238     pStack stack = createEmptyStack();
    239     while(t || !isStackEmpty(stack)){
    240         while(t){
    241             printf("%c ",t->element);
    242             push(stack,t);
    243             t = t->left;
    244         }
    245 
    246         if(!isStackEmpty(stack)){
    247             t = pop(stack);
    248             t = t->right;
    249         }
    250 
    251     }
    252 
    253 }
    254 //中序遍历
    255 void middlerOrderTraversal(pBinTree tree){
    256     if(tree){
    257         middlerOrderTraversal(tree->left);
    258         printf("%c ",tree->element);
    259         middlerOrderTraversal(tree->right);
    260     }
    261 }
    262 
    263 //中序遍历的非递归方法
    264 void middlerOrderTraversalStack(pBinTree tree){
    265     pStack stack = createEmptyStack();
    266     pBinTree t =tree;;
    267     while(!isStackEmpty(stack) || t){
    268         while(t){
    269             push(stack,t);
    270             t=t->left;
    271         }
    272         if(!isStackEmpty(stack)){
    273             t = pop(stack);
    274             printf("%c ",t->element);
    275             t = t->right;
    276         }
    277     }
    278 
    279 }
    280 
    281 //后序遍历
    282 void postOrderTraversal(pBinTree tree){
    283     if(tree){
    284         postOrderTraversal(tree->left);
    285         postOrderTraversal(tree->right);
    286         printf("%c ",tree->element);
    287     }
    288 }
    289 
    290 //后序遍历的非递归方法
    291 void postOrderTraversalStack(pBinTree tree){
    292     pBinTree t = tree;
    293     pStack stack = createEmptyStack();
    294     while(t || !isStackEmpty(stack)){
    295         while(t){
    296             t->flag=0;
    297             push(stack,t);
    298             t=t->left;
    299         }
    300         if(!isStackEmpty(stack)){
    301             t = pop(stack);
    302             if(t->flag==0){
    303                 t->flag=1;
    304                 push(stack,t);
    305                 t=t->right;
    306             }else{
    307                 printf("%c ",t->element);
    308                 t=NULL;
    309             }
    310         }
    311     }
    312 }
    313 
    314 /*二叉树的层次遍历*/
    315 void levelOrderTraversal(pBinTree tree){
    316     pQueue queue = createEmptyQueue();
    317     pBinTree tr = tree;
    318     if(!tree){
    319         return;
    320     }
    321     addQueue(queue,tr);
    322     while(!isQueueEmpty(queue)){
    323         tr = deleteQueue(queue);
    324         printf("%c ",tr->element);
    325         if(tr->left){
    326             addQueue(queue,tr->left);
    327         }
    328         if(tr->right){
    329             addQueue(queue,tr->right);
    330         }
    331     }
    332 }
    333 
    334 /*Application of binary tree teaversal*/
    335 
    336 //get the mount of leaf node,we just need add condition at preOrderTraversal
    337 int getMountOfLeaves(pBinTree tree){
    338     pStack stack = createEmptyStack();
    339     pBinTree tr =tree;
    340     int mount=0;
    341     while(tr || !isStackEmpty(stack)){
    342         while(tr){
    343             if(tr->left==NULL && tr->right==NULL){
    344                 mount++;
    345             }
    346             push(stack,tr);
    347             tr=tr->left;
    348         }
    349         if(!isStackEmpty(stack)){
    350             tr = pop(stack);
    351             tr=tr->right;
    352         }
    353     }
    354     return mount;
    355 }
    356 
    357 /*get the height of  binary tree, the hight of binary is max(subLeftTree,subRightTree)*/
    358 int getHeigthOfBinaryTree(pBinTree tree){
    359     int hl,hr,maxH;
    360     if(tree){
    361         hl=getHeigthOfBinaryTree(tree->left);
    362         hr=getHeigthOfBinaryTree(tree->right);
    363         maxH=(hl>hr)?hl:hr;
    364         return maxH+1;
    365     }
    366     return 0;
    367 }
    368 
    369 //非递归的方法获取二叉树的高度,其实二叉树的高度就是栈中元素的最大值
    370 int getHeigthOfBinaryTreeStack(pBinTree tree){
    371     pBinTree t = tree;
    372     int hMax=0,stackSize;
    373     pStack stack = createEmptyStack();
    374     while(t || !isStackEmpty(stack)){
    375         while(t){
    376             t->flag=0;
    377             push(stack,t);
    378             t=t->left;
    379         }
    380         if(!isStackEmpty(stack)){
    381             t = pop(stack);
    382             if(t->flag==0){
    383                 t->flag=1;
    384                 push(stack,t);
    385                 t=t->right;
    386             }else{
    387                 /*这里已经弹栈一个元素,因此栈的容量应为 getSize+1*/
    388                 stackSize=getStackSize(stack)+1;
    389                 //printf("stackSize %d",stackSize);
    390                 if(stackSize>hMax){
    391                     hMax=stackSize;
    392                 }
    393                 t=NULL;
    394             }
    395         }
    396     }
    397     return hMax;
    398 }
    399 
    400 
    401 
    402 void main(){
    403     char s[]="A(B(D,F(E)),C(G(,H),I))";
    404     //char s[]="A(B,C)";
    405     pBinTree root =createBinTree(s);
    406     printf("preOrderTraversal
    ");
    407     preOrderTraversal(root);
    408     printf("
    PreOrderTraversalStack
    ");
    409     preOrderTraversalStack(root);
    410 
    411     printf("
    
    ================================
    ");
    412 
    413     printf("
    middleOrderTraversal
    ");
    414     middlerOrderTraversal(root);
    415     printf("
    middleOrderTraversalStack
    ");
    416     middlerOrderTraversalStack(root);
    417 
    418     printf("
    
    ================================
    ");
    419 
    420     printf("
    postOrderTraversal
    ");
    421     postOrderTraversal(root);
    422     printf("
    postOrderTraversalStack
    ");
    423     postOrderTraversalStack(root);
    424 
    425     printf("
    
    ================================
    ");
    426 
    427 
    428     printf("
    The level order traversal
    ");
    429     levelOrderTraversal(root);
    430 
    431     printf("
    
    =========the application of binary tree traversal===========
    ");
    432     int leavesMount = getMountOfLeaves(root);
    433     printf("
    number one:get the leaves mount:%d
    ",leavesMount);
    434 
    435     int maxHeight = getHeigthOfBinaryTreeStack(root);
    436     printf("
    nuber two:get height of the binary tree:%d",maxHeight);
    437 
    438 }
    二叉树的相关操作

    下面是代码中使用二叉树“A(B(D,F(E)),C(G(,H),I))”的图解,方便大家理解

    代码的运行结果:

  • 相关阅读:
    ASP.NET HTTP模块和处理程序(5)(转载)
    充分利用ASP.NET的三种缓存提高站点性能(转载)
    LINQ体验(4)——LINQ简介和LINQ to SQL语句之Where
    理解DataSet的数据缓存机制
    在ASP.NET中实现AJAX(一)
    ASP.NET HTTP模块和处理程序(2)(转载)
    ASP.NET HTTP模块和处理程序(1)(转载)
    aspx页面中文汉字显示为乱码
    贫血还是充血?(转载)
    ASP.NET HTTP模块和处理程序(3)(转载)
  • 原文地址:https://www.cnblogs.com/yghjava/p/6682989.html
Copyright © 2020-2023  润新知