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


    二叉树

    • 每个节点上最多有两个子节点
    • 满二叉树
      • 所有叶子节点都在最后一层
      • 总数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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    查找

    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    删除

    • 删除
      • 如果删除的节点是叶子节点,删除该节点
      • 如果删除的节点非叶子节点,删除该子树
    • 判断子节点是否需要删除
      • 如果左子节点需要删除,则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);
            }
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    // BinaryTree
    public void delNode(int no){
        if(root!=null){
            if(root.getNo()==no){
                root = null;
            }else{
                root.delNode(no);
            }
        }else{
            System.out.println("空树,不能为空");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    顺序存储二叉树

    • 顺序存储二叉树
      • 完全二叉树
      • 第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);
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    线索二叉树

    • 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    线索化二叉树遍历

    // 遍历线索化二叉树
    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    堆排序

    • 堆排序
      • 旋转排序
      • 完全二叉树
      • 大顶堆
        • 每个节点大于等于左右节点的值
        • 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值放到调整后的位置
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
  • 相关阅读:
    postfix 禁用附件功能
    地图资源下载工具数据在线、离线查询及数据激活功能
    【Vue全家桶】--- 第六章:vue-router
    @GlobalLock注解作用与原理解析
    [山东科技大学OJ]1141 Problem E: 编写函数:有序序列插入数据 之二 (Append Code)
    Springboot----实现邮箱验证码登录(代码部分)
    二、初识FreeRTOS之FreeRTOS入门
    geemap学习笔记011:可视化遥感影像随时间的变化
    一加Nord N300 5G什么时候发布 一加Nord N300 5G配置如何
    linux中利用fork复制进程,printf隐藏的缓冲区,写时拷贝技术,进程的逻辑地址与物理地址
  • 原文地址:https://blog.csdn.net/weixin0605/article/details/125530631