zoukankan      html  css  js  c++  java
  • 二叉树的一些学习

    转:https://xiaozhuanlan.com/topic/5036471892

    二叉树性质
    1)在二叉树的第i层上最多有2i-1 个节点 。(i>=1)
    2)二叉树中如果深度为k,那么最多有2k-1个节点。(k>=1)
    3)n0=n2+1 n0表示度数为0的节点数,n2表示度数为2的节点数。
    4)在完全二叉树中,具有n个节点的完全二叉树的深度为[log2n]+1,其中[log2n]是向下取整。
    5)若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点有如下特性:
      (1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;
      (2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
      (3) 若 2i+1>n,则该结点无右孩子结点, 否则,编号为2i+1 的结点为其右孩子结点。


    二叉树遍历
    前序遍历 :通俗的说就是从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左再向右的方向访问。
    中序遍历 :就是从二叉树的根结点出发,当第二次到达结点时就输出结点数据,按照先向左再向右的方向访问。
    后序遍历 :就是从二叉树的根结点出发,当第三次到达结点时就输出结点数据,按照先向左再向右的方向访问。
    层序遍历 :层次遍历就是按照树的层次自上而下的遍历二叉树。

    *虽然二叉树的遍历过程看似繁琐,但是由于二叉树是一种递归定义的结构,故采用递归方式遍历二叉树的代码十分简单。

    void PreOrderTraverse(BiTree T)
    {
        if(T==NULL)
        return;
        printf("%c", T->data);  /*显示结点数据,可以更改为其他对结点操作*/
        PreOrderTraverse(T->lchild);    /*再先序遍历左子树*/
        PreOrderTraverse(T->rchild);    /*最后先序遍历右子树*/
    }
    
    
    /*二叉树的中序遍历递归算法*/
    void InOrderTraverse(BiTree T)
    {
        if(T==NULL)
        return;
        InOrderTraverse(T->lchild); /*中序遍历左子树*/
        printf("%c", T->data);  /*显示结点数据,可以更改为其他对结点操作*/
        InOrderTraverse(T->rchild); /*最后中序遍历右子树*/
    }
    
    
    /*二叉树的后序遍历递归算法*/
    void PostOrderTraverse(BiTree T)
    {
        if(T==NULL)
        return;
        PostOrderTraverse(T->lchild);   /*先后序遍历左子树*/
        PostOrderTraverse(T->rchild);   /*再后续遍历右子树*/
        printf("%c", T->data);  /*显示结点数据,可以更改为其他对结点操作*/
    }

    将二叉树按中序遍历得到一个有序的数组结果,某个节点元素的前后相邻的节点即为前驱节点,后区节点

    前驱节点
    1:如果当前节点的左子树不为空,那么该点的前驱节点为该点左子树中最右的节点。
    2:如果当前节点的左子树为空,那么该点的前驱节点为从该点往上延伸,如果延伸到的点为其父亲节点的右孩子,那么这个父亲节点就是该点的前驱节点。

    后驱节点
    1:如果当前节点的右子树不为空,那么该点的后驱节点为该点右子树中最左的节点。
    2:如果当前节点的右子树为空,那么该点的后驱节点为从该点往上延伸,如果延伸到的点为其父亲节点的左孩子,那么这个父亲节点就是该点的后驱节点。

    struct node
    {
        node left;//左孩子
        node right;//右孩子
        node parent;//父亲节点
        int value;
    };
    
    node getfristornode(node heap)//heap代表当前要找前驱节点的节点
    {
        if(heap==null)//如果当前节点为空,返回空
            return heap;
        if(heap.left!=null)//如果当前节点左子树不为空,那么该节点的后继节点为左子树中最右的节点
            return getrightmost(heap.left);//找到左子数树中最右的节点,并返回
        else                               //如果程序到达这里,说明当前节点的左子数为空
        {
            node parent=heap.parent;
    
           //第一个条件就是判断那种特殊情况的,一直延伸到当前节点没有父亲节点时,那么parent为空,这个条件不满足,函数返回空
           //第二个条件是判断当前节点是否为该父亲节点的右孩子,如果不是,继续执行下面的代码,如果是,说明这个父亲节点就是heap节点的前驱节点
            while (parent!=null&&heap!=parent.right)
            {                                       
                heap=parent;
                parent=heap.parent;
            }
            return parent;
        }
    }
    
    //这个函数是求左子树中最右的节点的函数
    getrightmost(node heap)
    {
        while (heap!=null)
            heap=heap.right;
        return heap.parent;
     
    }

    上面是前驱节点的查找方式,后区节点基本相同,左右换下。

  • 相关阅读:
    Binary Tree Inorder Traversal
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Majority Element
    Excel Sheet Column Number
    Reverse Bits
    Happy Number
    House Robber
    Remove Linked List Elements
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/isawu/p/11135866.html
Copyright © 2011-2022 走看看