学习笔记-算法-9-二叉树-1

28 篇文章 0 订阅
18 篇文章 0 订阅

二叉树

  • 每个节点上最多有两个子节点
  • 满二叉树
    • 所有叶子节点都在最后一层
    • 总数2^n-1
  • 完全二叉树
    • 最后一层所有子节点左边连续
    • 倒数第二层叶子节点右边连续

遍历

  • 遍历
    • 前序
      • 先输出当前节点
      • 如果左子节点不为空,则递归前序遍历
      • 如果右子节点不为空,则递归前序遍历
    • 中序
      • 如果当前节点左子节点不为空,则递归中序遍历
      • 输出当前节点
      • 如果当前节点右子节点不为空,则递归中序遍历
    • 后序
      • 如果当前节点左子节点不为空,则递归中序遍历
      • 如果当前节点右子节点不为空,则递归中序遍历
      • 输出当前节点
public class Demo{
    public static void main(String[] args){
        // 创建二叉树
        BinaryTree binaryTree = new BinaryTree();
        HeroNode node1 = new HeroNode(1."xx");
        HeroNode node2 = new HeroNode(2."xx");
        HeroNode node3 = new HeroNode(3."xx");
        HeroNode node4 = new HeroNode(4."xx");
        HeroNode node5 = new HeroNode(5."xx");
        
        root1.setLeft(node2);
        root1.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);
        
        // 前序
        binaryTree.preOrder();
        // 中序
        binaryTree.infixOrder();
        // 后续
        binaryTree.postOrder();
    }
}

class BinaryTree{
    private HeroNode root;
    public void setRoot(HeroNode root){
        this.root = root;
    }
    // 前序遍历
    public void preOrder(){
        if(this.root != null){
            this.root.preOrder();
        }else{
            System.out.println("二叉树为空");
        }
    }
    // 中序
    public void infixOrder(){
        if(this.root != null){
            this.root.infixOrder();
        }else{
            System.out.println("二叉树为空");
        }
    }
    // 后续
    public void postOrder(){
        if(this.root != null){
            this.root.postOrder();
        }else{
            System.out.println("二叉树为空");
        }
    }
}

class HeroNode{
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;
    public HeroNode(int no,String name){
        super();
        this.no = no;
        this.name = name;
    }
    // get set
    // toString no name
    
    // 前序遍历
    public void preOrder(){
        // 先输出父节点
        System.out.println(this);
        if(this.left!=null){
            this.left.preOrder();
        }
        if(this.right!=null){
            this.right.preOrder();
        }
    }
    
    // 中序遍历
    public void infixOrder(){
        if(this.left!=null){
            this.left.preOrder();
        }
        // 先输出父节点
        System.out.println(this);
       
        if(this.right!=null){
            this.right.preOrder();
        }
    }
    
    // 后续遍历
    public void postOrder(){
        if(this.left!=null){
            this.left.preOrder();
        }
        if(this.right!=null){
            this.right.preOrder();
        }
        // 先输出父节点
        System.out.println(this);
    }
}

查找

class HeroNode{
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;
    public HeroNode(int no,String name){
        super();
        this.no = no;
        this.name = name;
    }
    // get set
    // toString no name
    
       // 前序查找
    public HeroNode preOrderSearch(int no){
        if(this.no == no){
            return this;
        }
        HeroNode resNode = null;
        if(this.left!=null){
            resNode = this.left.preOrderSearch(no);
        }
        if(resNode!=null){
            // 找到
            return resNode;
        }
        if(this.right!=null){
            resNode = this.right.preOrderSearch(no);
        }
        return resNode;
    }
    // 中序查找
    public HeroNode infixOrderSearch(){
        HeroNode resNode = null;
        if(this.left!=null){
            resNode = this.left.infixOrderSearch(no);
        }
        if(resNode!=null){
            // 找到
            return resNode;
        }
        if(this.no == no){
            return this;
        }
        if(this.right!=null){
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }
    // 后续
    public HeroNode postOrderSearch(){
        HeroNode resNode = null;
        if(this.left!=null){
            resNode = this.left.postOrderSearch(no);
        }
        if(resNode!=null){
            // 找到
            return resNode;
        }
        if(this.right!=null){
            resNode = this.right.postOrderSearch(no);
        }
        if(resNode!=null){
            // 找到
            return resNode;
        }
        if(this.no == no){
            return this;
        }
        return resNode;
    }
}

删除

  • 删除
    • 如果删除的节点是叶子节点,删除该节点
    • 如果删除的节点非叶子节点,删除该子树
  • 判断子节点是否需要删除
    • 如果左子节点需要删除,则this.left = null
    • 如果右子节点需要删除,则this.right = null
    • 如果没有删除,向左递归
    • 如果没有删除,向右递归
class HeroNode{
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;
    public HeroNode(int no,String name){
        super();
        this.no = no;
        this.name = name;
    }
    // get set
    // toString no name
    
    // 删除
    public void delNode(int no){
        if(this.left!=null &7 this.left.no == no){
            this.left = null;
            return;
        }
        if(this.right!=null&&this.right.no == no){
            this.right = null;
            return;
        }
        if(this.left != null){
            this.left.delNode(no); 
        }
        if(this.right!= null){
            this.right.delNode(no);
        }
    }
}


// BinaryTree
public void delNode(int no){
    if(root!=null){
        if(root.getNo()==no){
            root = null;
        }else{
            root.delNode(no);
        }
    }else{
        System.out.println("空树,不能为空");
    }
}

顺序存储二叉树

  • 顺序存储二叉树
    • 完全二叉树
    • 第n个元素的左子节点2n+1
    • 第n个元素的右子节点2n+2
    • 第n个元素的父节点(n-1)/2
public class Demo{
    public sttaic void main(String[] args){
        int[] arr = {1,2,3,4,5,6,7};
        ArrBinaryTree arrBinary = new ArrBinaryTree(arr); 
        arrBinary.preOrder(0);// 124367
        
    }
}

class ArrBinaryTree{
    private int[] arr;
    
    public ArrBinaryTree(int[] arr){
        this.arr = arr;
    }
    
    // 编写一个方法,完成顺序二叉树的前序遍历
    public void preOrder(int index){
        // 如果数组为空 或者arr.length = 0
        if(arr==null|| arr.length==0){
            System.out.println("数组为空,不能前序遍历");
        }
        // 输出当前元素
        Systm.out.println(arr[index]);
        // 向左递归遍历
        if((index*2+1)<arr.length){
            preOrder(2*index + 1);
        }
        // 向右遍历递归
        if((index*2+2)<arr.length){
            preOrder(2*ubdex+2);
        }
    }

}

线索二叉树

  • n个二叉链表有n+1个空指针域
  • 前序线索二叉树
  • 中序线索二叉树
  • 后序线索二叉树
public class Demo{
    public static void main(String[] args){
        
    }
}

class BinaryTree{
    private HeroNOde root;
    
    // 指向当前节点的前驱节点的指针
    private HeroNode pre = null;
    
    // setRoot
    
    public void threadedNotes(HeroNode node){
        // node 当前需要线索化的节点
        if(node==null){
            return ;
        }
        // 中序线索化
        // 1 先处理左子树
        threadedNodes(node.getLeft())
        // 2 当前记得拿
        // 当前节点的前驱
        if(node.getLeft()==null){
            // 当前节点左指针指向前驱节点
            node.setLeft(pre);
            // 相爱当前节点左指针类型
            node.setLeftType(1);
        }
        // 处理前驱节点
        if(pre!=null&& pre.getRight()==null){
            pre.setRight(node);
            pre.setRightType(1);
        }
        // 处理一个节点后,当前节点变成下一个节点的前驱节点 
        pre = node;
        // 3 处理右子树
        threadedNodes(node.getRight())
    }
}

calss HeroNode{
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;
    
    // 0 左子树 1 前驱节点
    private int leftType;
    // 0 右子树 1 后继节点
    private int rigthType;
}

线索化二叉树遍历

// 遍历线索化二叉树
public void threadedList(){
    // 定义一个遍历 存储当前遍历的系欸但 从root开始
    HeroNode node = root;
    while(node!=null){
        // 循环找到leftType==1的系欸但
        // 后面随着遍历而发生变化
        while(node.getLeftType()==0){
            node = node.getLeftType();
        }
        // 打印当前节点
         System.out.println(node);
        // 如果当前系欸但右指针指向是后继节点,就一直输出
        while(node.getRightType()==1){
            // 获取当前系欸但的后继节点
            node = node.getRight();
            System.out.println(node);
        }
        // 替换这个遍历节点
        node = node.getRight();
    }
}

堆排序

  • 堆排序
    • 旋转排序
    • 完全二叉树
    • 大顶堆
      • 每个节点大于等于左右节点的值
      • arr[i]>=arr[2i+1]&&arr[i]>=arr[2i+2]
    • 小顶堆
      • 每个节点但小于等于左右节点的值
      • arr[i]<=arr[2i+1]&&arr[i]<=arr[2i+2]
public class HeapSort{
    public static void main(String[] args){
        int[] arr = {4,6,8,5,9};
    }
    
    public static void heapSort(int arr[]){
        System.out.println("堆排序");
        // 将无序数组构成一个堆(大顶堆)
        for(int i=arr.length/2-1;i>=0;i--){
            adjustHeap(arr,i,arr.length);
        }
        // 将堆顶元素与尾元素交换(最大元素下沉到末尾)
        // 重新调整结构,再次满足堆定义
        for(int j=arr.length-1;j>0;j--){
            // 交换
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr,0,j)
        }
        
    }
    
    // 将数组调整为大顶堆
    // arr 待调整的数组
    // i 非叶子节点数组索引
    // length 对多少个元素进行调整,逐渐减少
    public void static adjustHeap(int arr[],int i,int length){
        // 先取出当前元素的值,保存在零时变量
        int temp = arr[i];
        // k=i*2+1 k是i的左子节点
        for(int k=i*2+1;k<length;k=k*2+1){
            if(k+1<length && arr[k]<arr[k+1]){// 左子节点小于右子节点
                k++;
            }
            if(arr[k]>temp){// 子节点大于父节点
                arr[i] = arr[k]; // 较大值赋给当前节点
                i = k; // i指向k,继续循环
            }else{
                break;
            }
        }
        // 循环结束,已经将i为父节点的树最大值,放在了局部最顶
        arr[i] = temp; // 将temp值放到调整后的位置
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值