zoukankan      html  css  js  c++  java
  • C 二叉树

    二叉树表示法
    P127页
    /*
    typedef struct BiTNode
    {
        int        data;
         struct BiTNode *lchild, *rchild;
    }BiTNode, *BiTree;
    */
    
    struct BiTNode
    {
        int        data;
        struct BiTNode *lchild, *rchild;
    };
    
    typedef struct BiTNode BiTNode;
    typedef struct BiTNode * BiTree;
    
    树的三叉链表表示
    //三叉链表
    typedef struct TriTNode 
    {
        int data;
        //左右孩子指针
        struct TriTNode *lchild, *rchild;
        struct TriTNode *parent;
    }TriTNode, *TriTree;
    
    双亲链表法
    //双亲链表
    #define MAX_TREE_SIZE 100
    typedef struct BPTNode
    {
        int data;
        int parentPosition; //指向双亲的指针 //数组下标
        char LRTag; //左右孩子标志域
    }BPTNode;
    
    typedef struct BPTree
    {
        BPTNode nodes[100]; //因为节点之间是分散的,需要把节点存储到数组中
        int num_node;  //节点数目
        int root; //根结点的位置 //注意此域存储的是父亲节点在数组的下标
    }BPTree;
    //用这个数据结构能表达出一颗树,为什么?
    4.4.3二叉树的遍历
    二叉树编程实践
    基本操作
    typedef struct node{
       int  data; 
       struct node *lchild,*rchild;
    } NODE;
    NODE *root; 
    
    DLR(NODE *root )
    {  
        if (root) //非空二叉树
        {
    printf(“%d”,root->data); //访问D
    DLR(root->lchild); //递归遍历左子树
    DLR(root->rchild); //递归遍历右子树
        }
    }
    
    中序遍历算法
    LDR(NODE *root)
    { if(root !=NULL)
      {  LDR(root->lchild);
          printf(“%d”,root->data);
          LDR(root->rchild); 
      } }
    
    后序遍历算法
    LRD (NODE *root)
    {if(root !=NULL) 
       {LRD(root->lchild);
         LRD(root->rchild);
         printf(“%d”,root->data); 
       } }
    计算二叉树中叶子结点的数目
    int sum = 0; //全局变量
    DLR_CountLeafNum(NODE *root)//采用中序遍历的递归算法
    { 
       if ( root)  //非空二叉树条件,还可写成if(root !=NULL )
      {   if(!root->lchild&&!root->rchild)  //是叶子结点则统计并打印
          {   sum++;     printf("%d
    ",root->data);  }
          DLR_CountLeafNum(root->lchild); //递归遍历左子树,直到叶子处;
          DLR_CountLeafNum(root->rchild);}//递归遍历右子树,直到叶子处;
      } return(0);  
    }   
    思想:    1)求根结点左子树的叶子结点个数,累计到sum中,求根结点右子树的叶子结点个数累计到sum中。
            2)若左子树还是树,重复步骤1;若右子树还是树,重复步骤1。
            3)全局变量转成函数参数
            4)按照先序、中序、后序方式计算叶子结点,
    ===》三种遍历的本质思想强化:访问结点的路径都是一样的,计算结点的时机不同。
    求二叉树的深度
        思想:    1)求根结点左子树高度,根结点右子树高度,比较的子树最大高度,再+12)若左子树还是树,重复步骤1;若右子树还是树,重复步骤1。
    完全Copy二叉树 
        思想:    1)malloc新结点,
    2)拷贝左子树,拷贝右子树,让新结点连接左子树,右子树
    3)若左子树还是树,重复步骤1、2;若右子树还是树,重复步骤1、2
    树的非递归遍历(中序遍历)
    中序 遍历的几种情况
    分析1:什么时候访问根、什么时候访问左子树、什么访问右子树
           当左子树为空或者左子树已经访问完毕以后,再访问根
           访问完毕根以后,再访问右子树。
    分析2:非递归遍历树,访问结点时,为什么是栈,而不是其他模型(比如说是队列)。
            先走到的后访问、后走到的先访问,显然是栈结构
    分析3:结点所有路径情况
    步骤1:
    如果结点有左子树,该结点入栈;
    如果结点没有左子树,访问该结点;
    步骤2:
    如果结点有右子树,重复步骤1;
    如果结点没有右子树(结点访问完毕),根据栈顶指示回退,访问栈顶元素,并访问右子树,重复步骤1
    如果栈为空,表示遍历结束。 
    注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。
    分析4:有一个一直往左走入栈的操作,中序遍历的起点
    3、#号法编程实践
    利用前序遍历来建树(结点值陆续从键盘输入,用DLR为宜)
    Bintree createBTpre( )
    {      
    Bintree T; 
    char ch;
            scanf(“%c”,&ch);
            if(ch==’#’) 
    T=NULL; 
            else
            {   T=( Bintree )malloc(sizeof(BinTNode));
                T->data=ch;
                T->lchild=createBTpre(); 
                T->rchild=createBTpre();
            }        
            return T;
    }
    
    //后序遍历销毁一个树
    void  BiTree_Free(BiTNode* T)
    {
        BiTNode *tmp = NULL;
        if (T!= NULL)
        {
            if (T->rchild != NULL) BiTree_Free(T->rchild);
            if (T->lchild != NULL) BiTree_Free(T->lchild);
            if (T != NULL)
            {
                free(T); 
                T = NULL;
            }
        }
    }
  • 相关阅读:
    CF 526F Max Mex(倍增求LCA+线段树路径合并)
    CoderForces Round526 (A~E)题解
    牛客OI周赛4-提高组 A K小生成树(kmst)
    Codeforces 1072 C
    Codeforces 1053 C
    牛客国庆集训派对Day3 B Tree
    牛客国庆集训派对Day3 I Metropolis
    牛客国庆集训派对Day3 A Knight
    牛客国庆集训派对Day3 G Stones
    Codeforces 1053 B
  • 原文地址:https://www.cnblogs.com/yaowen/p/4812298.html
Copyright © 2011-2022 走看看