二叉树删除结点和顺序存储二叉树

1.二叉树删除结点
2.顺序存储二叉树

二叉树删除结点其实是将我们要删除的节点与他的父节点没有联系也就是将父结点给要删除的结点位置置空。比如说root.left = null或者root.right = null;下面我们上代码进行分析先简单有一个思路

//下面为实体类里面的代码块
//二叉树删除结点
    public void delNode(int no) {   
        if (this.left != null && this.left.no == no) {//
           // if (this.left.left == null && this.left.right == null) {
                this.left = null;
                return;
         //   } else {
         //       HeroNode temp = this.left.left;
          //      HeroNode temp2 = this.left.right;
         //       this.left = temp;
          //      temp.right = temp2;
          //      return;
         //   }
        }
        if (this.right != null && this.right.no == no) {
          //  if (this.right.left == null && this.right.right == null) {
                this.right = null;
                return;
          //  } else {
          //      HeroNode temp = this.right.left;
          //      HeroNode temp2 = this.right.right;
          //      this.right = temp;
          //      temp.right = temp2;
          //      return;
          //  }
        }
        if (this.left != null) {
            this.left.delNode(no);
        }
        if (this.right != null) {
            this.right.delNode(no);
        }
    }
     //下面为树对象里面的代码块
     //二叉树删除结点
    public void delNode(int no){
        if (root != null) {
            if (root.getNo() == no) {
                root = null;
                return;
            } else {
                this.root.delNode(no);
            }
        }else {
            System.out.println("空树不能删除");
        }
    }

我尽可能呢在代码中注释出来首先我们肯定要先找根节点的编号,看看根节点是否是我们需要删除的结点,然后我们再找子节点。所以我们在实体类中的方法我们默认已经检查过根节点的编号了。所以我们直接1.先判断左子节点如果不为空并且左子节点就是我们需要删除的结点。2.直接让根结点的左子节点置空就可以。3.我们判断右子节点不为空并且右子节点的编号就是我们需要删除的编号4.我们直接让右子节点置空就可以。如果左右子节点都不为空并且编号并不是我们需要删除的编号,那么我们直接递归左右遍历删除即可。

我把其中的一些代码给注释了是因为这样简单一点,大家可以放出来看一下我写的代码是什么意思。其实就是比如说我需要删除的结点他还有子节点怎么办?
因为通过简单的删除是回把待删除结点以及他的子节点一次性全部删除的,但是我觉得这样不好,所以我做个改进使待删除结点的左子节点上来继位。右子节点跟在其后。

二、顺序存储二叉树
首先我先上代码块然后为各位讲解

public class AddTree {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5,6,7};
        Arr arr1 = new Arr(arr);
        arr1.postOrder();
    }
}

class Arr{
    private int[] arr;
    public Arr(int[] arr) {
        this.arr = arr;
    }
    public void preOrder(){
        this.preOrder(0);
    }
    //前序遍历
    public void preOrder(int index){
        if (arr == null || arr.length == 0){
            System.out.println("数组为空不能遍历");
        }
        System.out.println(arr[index]);
        if ((index*2+1)<arr.length){
            preOrder(index*2+1);
        }
        if ((index*2+2)<arr.length){
            preOrder(index*2+2);
        }
    }
    public  void initOrder(){
        this.initOrder(0);
    }
    //中序遍历
    public void initOrder(int index){
        if (arr == null || arr.length == 0){
            System.out.println("数组为空不能遍历");
        }
        if ((index*2+1)<arr.length){
            initOrder(index*2+1);
        }
        System.out.println(arr[index]);
        if ((index*2+2)<arr.length){
            initOrder(index*2+2);
        }
    }

    public void postOrder(){
        this.postOrder(0);
    }
    //后续遍历
    public void postOrder(int index){
        if (arr == null ||arr.length == 0){
            System.out.println("数组为空不能遍历");
        }
        if ((index*2+1)<arr.length){
            postOrder(index*2+1);
        }
        if ((index*2+2)<arr.length){
            postOrder(index*2+2);
        }
        System.out.println(arr[index]);
    }
}

在这里插入图片描述
根据上图我们可以得出一个结论。。。当然这个结论不是我得出的。。就是每个地方的所以和父节点的索引都是有关系的 左子节点的索引值为父节点的索引值2+1 可以举个例子比如说2结点的索引值是1父节点的索引值是0 那么 1 = 02 +1 右子节点3的索引值是2 父节点索引值是0 右子节点的索引值等于父节点索引值 * 2 + 2 所以 2 = 0 * 2 + 2。如果我们搞懂这个 ,那么代码就不难看懂了。这里我只讲一个前序存储,中序和后序存储各位自己写一下吧。上面的参考代码我给了。
前序存储呢其实很简单。首先都是通常要做的就是先判断你给我的数组是不是空的呢或者长度为0呢。如果是的话,那我们就不用继续操作了。如果不为空或者0那么我们再继续操作好吧。首先我们传入的参数是索引值因为是顺序存储所以到时候传进去我们默认是从根节点开始所以先输出的是arr[0],左边索引值如果比数组长度小的话那么就继续向左子树进行递归遍历。直到找到左子树最后一个左叶子结点并且找到一个输出一个然后再向右递归存储和左边一样。

今天所讲的其实都挺容易的,大家多练几遍多看看代码应该是没有那么难的了。下一期我们讲一下线索化二叉树。为下下期的重头堆排序做十足的准备。

最后还是希望大家能够指认我的错误,谢谢大家。希望能和大家一起共同进步!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值