day 7 大顶堆和小顶堆 二叉排序树

大顶堆 堆排序 例子

import java.lang.reflect.Array;
import java.util.Arrays;

public class heapSortTest {
    public static void main(String[] args) {
        int []x = {4,6,8,5,9};
        heapSort heapSort = new heapSort();
        heapSort.setHeapSort(x);
        System.out.println(Arrays.toString(x));
        heapSort.dpx(x);
    }
}
//堆排序
class heapSort{
    int temp;//用来堆排序时 当跳板 来交换值
    //利用堆排序给数组排序
    public void dpx(int []x){
        //调用堆排序方法 先将数组转换为大顶堆
        setHeapSort(x);
        //然后按照顺序从最后一个元素 到根节点的后面一个元素(也就是不包括根节点) 进行循环
        for (int i=x.length-1;i>0;i--){
            //交换根节点的值和 i当前所表示的索引的值
            temp = x[i];
            x[i] = x[0];
            x[0] = temp;
            //调整交换过后的数组再次为大顶堆(因为现在调整的是 去除根节点原本那个最大值的数组(比较特殊) 为大顶堆 所以直接传入根节点 从上向下调整数组)
            setHeapSort(0,x,i);
        }
        //输出堆排序后的数组
        System.out.println(Arrays.toString(x));

    }
    //首先需要将数组转换为大顶堆的排序方式
    public void setHeapSort(int []x){
        //首先查看数组有没有被赋予值 和数组的长度是否为0
        if (x.length==0||x==null){
            return;
        }
        //x.length/2-1 代表的是当前顺序树的最后一个非叶子节点的节点   这个循环就是从这个节点到根节点的循环
        //因为转换堆排序的时候是从下至上 从左至右转换的
        for (int i =x.length/2-1 ; i >=0 ; i--) {
            //按照从下至上 从左至右转换的顺序轮流将所有非叶子节点的节点传入 即按顺序逐步将整个数组转换为大顶堆的排序
            setHeapSort(i,x,x.length);
        }
    }
    //一个数组实际是一个顺序树 将一个顺序树转换为大顶堆需要传入 当前根节点的索引 数组 和当前根节点代表的数的大小
    public void setHeapSort(int i,int []x,int arrlength){
        int temp = x[i];//先将当前根节点的值存起来(后续需要用到)
        //从当前节点的左子节点开始循环 每过一轮 g就变成刚才节点的左子节点的左子节点 知道那个节点不存在(索引超出数组长度)就结束循环
        for (int q=i*2+1;q<arrlength;q=q*2+1){
            //然后比较传入的节点的左右子节点之间的大小 q默认代表左子节点 如果右子节点的值大于他 那么q++ 使q代表右子节点
            if (q+1<arrlength&&x[q] < x[q+1]){
                q++;
            }
            //用索引为q的值跟传入的节点的值进行比较 如果x[q]>x[i] 那么把根节点的值变成q的值 并使i=q i代表q的索引 来保证根节点的值大于子节点
            if (x[q]>temp){
                x[i] = x[q];
                i = q;
            }else{//如果当前节点的子节点的值都小于自己 那么跳出循环
                break;
            }
        }
        //将temp 也就是根节点的值 付给x[i](如果当前节点的子节点的值大于自己 那么在里面进行判断过后 i现在就代表你交换的那个子节点的索引 如果不大于 那么他还是自己)
        x[i] = temp;
    }
}

二叉排序树例子

package test1;

public class binarySortTreeTest {
    public static void main(String[] args) {
        int []x = {5,3,9,7,6,4,2};
        String []z = {"阿狸","亚索","鱼人","猴子","琴女","螳螂","卡牌"};
        binarySortTree tree = new binarySortTree();
        for (int i = 0; i < x.length; i++) {
            tree.add(x[i],z[i]);
        }
        System.out.println("二叉排序树");
        tree.fixOrder();
//        node test1 = tree.searchf(9);
//        System.out.println(test1);
        System.out.println("删除后的二叉排序树");
        tree.delete(5);
        tree.fixOrder();

    }
}
//创建二叉排序树树
class binarySortTree{
    //根节点
    node root;


    public void add(int id, String name){
        if (root == null){
            root = new node(id,name);
        }else{
            node test = new node(id,name);
            root.add(test);
        }
    }
    //二叉排序树中序遍历
    public void fixOrder(){
        if (root == null){
            System.out.println("树空!!!!");
        }else{
            root.fixOrder();
        }

    }
    //搜索目标节点
    public node search(int id){
        if (root == null){
            return null;
        }
        return root.search(id);
    }
    //搜索目标节点的父节点
    public node searchf(int id){
        if (root == null){
            return null;
        }
        node mb = root.search(id);
        return root.searchf(mb);
    }
    //找以目标节点的右子节点为根节点的情况下 值最小的节点 获取并返回他的值 并删除这个最小节点
    public Object[] searchlittle(node node){
        while (node.left!=null){
            node = node.left;
        }
        Object[] mb = {node.id,node.name};
        node delmb = searchf(node.id);
        if (delmb.left==node){
            delmb.left = null;
        }else{
            delmb.right = null;
        }
        return mb;
    }
    //通过id删除目标节点
    public void delete(int id){
        node target = this.search(id);
        node ftarget = this.searchf(target.id);
        if (target != null){
                //目标节点没有子节点的情况
                if (target.left == null && target.right == null) {
                    if (ftarget.left == target) {
                        ftarget.left = null;
                    }
                    if (ftarget.right == target) {
                        ftarget.right = null;
                    }
                    //目标节点有两个子节点的情况
                }else if (target.left!=null&&target.right!=null){
                    Object[] x = searchlittle(target.right);
                    target.id = (int) x[0];
                    target.name = (String) x[1];

                    //那么剩下的就是只有一个子节点的情况
                }else{
                    if (ftarget!=null) {
                        if (ftarget.left == target) {
                            if (target.left != null) {
                                ftarget.left = target.left;
                            }
                            if (target.right != null) {
                                ftarget.left = target.right;
                            }
                        } else {
                            if (target.left != null) {
                                ftarget.right = target.left;
                            }
                            if (target.right != null) {
                                ftarget.right = target.right;
                            }
                        }
                    }else{
                        if (target.left!=null){
                            root = target.left;
                        }else{
                            root = target.right;
                        }
                    }
                }

        }else{
            System.out.println("未找到目标,删除失败!");
        }

    }
}
//创建节点
class node{
    //id
     int id;
     String name;
     node left;
     node right;
    public node(int id,String name){
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "node{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    //给二叉排序树添加节点
    public void add(node node){
        //如果传入的节点的id 小于 当前节点的值
        if (node.id < this.id){
            //并且当前根节点的左子节点为空 那么当前节点的左子节点就为 穿的的节点
            if (this.left == null){
                this.left = node;
            }else{
                //否则就以当前节点的左子节点为根节点继续添加
                this.left.add(node);
            }
        }else{
            if (this.right == null){
                this.right = node;
            }else{
                this.right.add(node);
            }
        }
    }
    //中序遍历二叉排序树
    public void fixOrder(){
        //如果当前节点的左子节点不为空 那么就以当前节点的左子节点为根节点继续找
        if (this.left!=null){
            this.left.fixOrder();
        }
        System.out.println(this);
        //同上
        if (this.right!=null){
            this.right.fixOrder();
        }
    }


    //二叉排序树删除节点

    //搜索目标节点
    public node search(int id){
        if (this.id == id){
            return this;
        }else if (id <this.id){
            return this.left.search(id);
        }else{
            return this.right.search(id);
        }
    }
    //搜索目标节点的父节点
    public node searchf(node mb){
        if (this.left!=null&&this.left==mb||this.right!=null&&this.right==mb ){
            return this;
        }
        if (mb.id < this.id){
            return this.left.searchf(mb);
        }
        if (mb.id > this.id){
            return this.right.searchf(mb);
        }
        return null;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值