二叉树的深度剖析上


文章目录

1.二叉树的定义

2.二叉树的存储

3.二叉树的基本操作

4.二叉树的前后序遍历

1.二叉树的定义

二叉树是指其结点的度都小于等于2的树形结构

满二叉树是指每除了叶子结点每个节点的度都为2的树形结构:

满二叉树是指一棵二叉树的深度为k,其结点总数为2的k次方-1的二叉树。

2.二叉树的性质

1.二叉树的结点总数比边数多1;

2.二叉树的叶子结点总数比度为2的结点总数多1,即N0=N2+1;那么这个公式是如何地出来的呢?

我们可以假设度为1的结点总数为N1,根据性质1我们可以得出这样一个方程N0+N1+N2-1=1*N1+2*N2;

3.在非空二叉树的结构中,每一行的结点总数为最多为2的(k-1)次方。

4.满二叉树是一种特殊的完全二叉树

5.在完全二叉树中,已知其结点总数为n,那么其深度为log2(n+1)向上取整。

6.二叉树的存储当中,我们通常采用孩子法来表示。

7.完全二叉树:对于深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从0到n-1的结点一一对应时称之为完全二叉树。

 像这棵树就是完全二叉树,而下面的这棵就不是

也就是说各个结点之间不能存在空格,像这个图里3的右子树没有,4的左子树结点就和7之间有了 空格,所以它也就不是完全二叉树。

例题:1.在具有2n个结点的完全二叉树中,叶子节点数是为

 像这种偶数个结点的情况必然有一个度为1的结点,所以可以得到 N0+N0-1=2*N-1,得出N0=n;

所以叶子节点数为n.

2.一个具有767个节点的完全二叉树,其叶子结点个数为:

 像这种奇数个节点的二叉树,一定没有度为1的结点,N0+N0-1=767,解出N0=384.

二.二叉树的存储用孩子法来进行存储:

class Shu
    {
        int val;
        Shu left;
        Shu right;

        public Shu(int val) {
            this.val = val;
        }
    }

三.前中后序遍历

前序遍历是指按照“根-左-右”的方式进行遍历,像这幅图前序遍历的结果是:1 2 3 4 5 6.前序遍历的代码实现:

public  void predisplay(Shu n)
    {
        if(n==null)
        {
           return;
        }
        System.out.print(n.val+"");
        predisplay(n.left);
        predisplay(n.right);
        //return

    }

中序遍历是按照“左-根-右”的方式进行遍历,遍历的结果是3 2 1 5 4 6,中序的遍历结果是:

public void middisplay(Shu n)
    {
        if(n==null)
        {
            return;
        }
        middisplay(n.left);
        System.out.print(n.val+"");
        middisplay(n.right);
    }

后序遍历是根据“左-右-根”的方式进行遍历,,遍历的结果是:3 2 5 6 4 1,后序遍历的结果是:

 public void houdisplay(Shu n)
    {
        if(n==null)
        {
            return;
        }
        houdisplay(n.left);
        houdisplay(n.right);
        System.out.print(n.val+"");
    }

3.层序遍历:层序遍历是一行一行的进行遍历:因此它的遍历结果是:1 2 4 3 5 6 ,代码实现为

public void fenceng(Shu a)
    {
        
        Queue<Shu> b=new LinkedList<>();//建立一个队列
        b.offer(a);
       

        while(!b.isEmpty())
        {
            int f= b.size();
            List<Shu> tmp=new ArrayList<>();
            while(f>0) {
               


                Shu c = b.poll();
                tmp.add(c);
                System.out.print(c.val + "");

               if(c.left!=null)
               {
                    b.offer(c.left);
                }
                if (c.right != null) {
                    b.offer(c.right);
                }
                f--;
            }
          



        }

    }

前中后序的常见选择题讲解:

1.二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK,中序遍历:HFIEJKG,则二叉树后序遍历序列为:

 这个题的解题思路就是E的左右两侧是  HFI和JKG,然后F的左右两侧是H I,H和I的左右两侧是null,G的左侧是J,J的右侧是K.,我们把结构图画出来就ok了。

2.设一棵二叉树的中序遍历:badce,后序遍历是:bdeca,则二叉树前序遍历序列为:

由后序遍历我们知道a是根结点,a的左右两侧分别是b、dce,c的左右两侧分别是 d和e,所以前序遍历的结果是a b c d e

四.二叉树的基本操作:

1.求总结点的个数:
总的结点个数等于根节点+叶子节点的个数

 public int size1(Shu root)
    {
        if(root==null)
        {
            return 0;
        }
        return size1(root.left)+size1(root.right)+1;
    }

2.求叶子结点的个数:叶子结点的左右子树分别为空

public int getLeafNodeCount(Shu n)
    {
        if(n==null)
        {
            return 0;
        }
        if(n.left==null&&n.right==null)
        {
            return 1;
        }
        else
        {
            return getLeafNodeCount(n.left)+getLeafNodeCount(n.right);
        }
    }

3.获取第k层节点的个数:等于左子树的k-1层结点个数+右子树的k-1层结点

 public int getKLeveInode(Shu n,int k)
    {
        if(n==null||k<=0)
        {
            return 0;
        }
        if(k==1)
        {
            return 1;
        }
        else
        {
            return getKLeveInode(n.left,k-1)+getKLeveInode(n.right,k-1);
        }


    }

public int getKLeveInode(Shu n,int k)
    {
        if(n==null||k<=0)
        {
            return 0;
        }
        if(k==1)
        {
            return 1;
        }
        else
        {
            return getKLeveInode(n.left,k-1)+getKLeveInode(n.right,k-1);
        }


    }

4.获取二叉树的高度:二叉树的高度等于左子树和右子树的高度较大的哪一个值加一

 public int getHeight(Shu root)
    {
        if(root==null)
        {
            return 0;
        }
        int a=getHeight(root.left);
        int b=getHeight(root.right);
        return a>b?a+1:b+1;

    }

5.检测值为value的元素是否存在:

public Shu find(Shu root,int val)
    {
        if(root==null)
        {
            return null;
        }
        if(root.val==val)
        {
            return root;
        }
        Shu a=find(root.left,val);
        if(a!=null)
        {
            return a;
        }
        Shu b=find(root.right,val);
        if(b!=null)
        {
            return b;
        }
        return null;



    }

}

6.层序遍历:实现一个队列,先放入一个元素,然后打印,再把它弹出,再把弹出的元素的左子树(不为空)放入,然后打印,右子树不为null的元素放入,然后打印,然后再弹出一个元素,然后依次类推,直到队列中元素为空。

public void fenceng(Shu a)
    {
        //List<List<Shu>> n=new ArrayList<>();

        Queue<Shu> b=new LinkedList<>();
        b.offer(a);
        //int i=0;

        while(!b.isEmpty())
        {
            int f= b.size();
            List<Shu> tmp=new ArrayList<>();
            while(f>0) {
                //List<Shu> tmp=new ArrayList<>();


                Shu c = b.poll();
                tmp.add(c);
                System.out.print(c.val + "");

               if(c.left!=null)
               {
                    b.offer(c.left);
                }
                if (c.right != null) {
                    b.offer(c.right);
                }
                f--;
            }
            //n.add(tmp);



        }

    }

7.完全二叉树的判断   这个题还是按照分层排序的思路,只不过是将null元素也放里面,当弹出的是null元素时,这时我们去判断队列当中的元素,如果全是null,那么它就是完全二叉树,否则则不是。

public boolean panduan(Shu a) {
        //List<List<Shu>> n=new ArrayList<>();
        if(a==null)
        {
            return true;
        }

        Queue<Shu> b = new LinkedList<>();
        b.offer(a);
        //int i=0;

        while (!b.isEmpty()) {
            //int f= b.size();
            //List<Shu> tmp=new ArrayList<>();

            //List<Shu> tmp=new ArrayList<>();


            Shu c = b.poll();
            if (c == null) {
                break;
            }
            //tmp.add(c);
            //System.out.print(c.val + "");


            b.offer(c.left);


            b.offer(c.right);
        }

        while (!b.isEmpty()) {

            Shu c = b.poll();
            if (c != null) {
                return false;
            }
        }
        return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值