Java语言实现简单的堆排序

本文详细介绍如何使用Java语言实现堆排序算法。首先定义Node类存储节点信息,然后通过创建完全二叉树并初始化节点来实现堆排序的第一步。接着,通过调整节点值构建大根堆,确保每个非叶节点的值不小于其子节点值。最后,通过对二叉树进行调整,将最大值依次放置于数组尾部,完成排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java语言实现简单的堆排序

直接切入正题。在这里实现一个一维数组的简单堆排序。
文字描述看的头痛,直接看图显得直观一些

摘自软件设计师教程
第一步:根据堆排序的定义,通过完全二叉树的方式去 实现,先定义一个Node类存放节点信息

class Node{
    Integer index;   //节点编号   节点编号的作用在第三步中会有体现
    Node parent;    //父节点
    Node left;      //左子节点
    Node right;     //右子节点
    Object data;    //数据
    public Node(){
        this.index = -1;
        this.parent = null;
        this.left = null;
        this.right = null;
        this.data = null;
    }
    public Node getParent() {
        return parent;
    }
    public Integer getIndex() {
        return index;
    }
    public void setIndex(Integer index) {
        this.index = index;
    }
    public void setParent(Node parent) {
        this.parent = parent;
    }
    public Node getLeft() {
        return left;
    }
    public void setLeft(Node left) {
        this.left = left;
    }
    public Node getRight() {
        return right;
    }
    public void setRight(Node right) {
        this.right = right;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
}

第二步,初始化二叉树,将数组中的元素放入Node中的data区保存,同时构建每个节点的双亲、左右孩子的关系

 //创建一棵树,为每个node节点添加双亲节点和子节点
    public static Node[] createTree(Object[] arr){
        Node[] tree = new Node[arr.length];
        for(int i = 0;i< tree.length;i++) {
            tree[i] = new Node();
            tree[i].setData(arr[i]);
            tree[i].setIndex(i);
            if (i != 0) {
                tree[i].setParent(tree[(i - 1) / 2]);
                if (tree[(i - 1) / 2].getLeft() == null) {
                    tree[(i - 1) / 2].setLeft(tree[i]);
                } else {
                    tree[(i - 1) / 2].setRight(tree[i]);
                }
            }
        }
        return tree;
    }

第三步:构造大根堆,调整每个节点的值,使得除叶子节点外的所有节点的data都不小于其左右子节点的data

 public static Node[] BigRootHeap(Node[] tree){
        int i = tree.length-1;
        while(i >=0){
            if(tree[i].getLeft() != null){
                if(tree[i].getRight() != null){
                    if(tree[i].getLeft().getData().hashCode() >=  tree[i].getRight().getData().hashCode()){
                        if(tree[i].getData().hashCode() < tree[i].getLeft().getData().hashCode()){
                            Object temp = tree[i].getData();
                            tree[i].setData(tree[i].getLeft().getData());
                            tree[i].getLeft().setData(temp);
                            /*当前节点和其左孩子交换data后可能会造成其左孩子的data小于它的左右孩子data,
                            因此,i需要跳转至其左左孩子节点的位置进行重新排序。下同*/
                            i = tree[i].getRight().getIndex();
                        }
                    }else{
                        if(tree[i].getData().hashCode() < tree[i].getRight().getData().hashCode()) {
                            Object temp = tree[i].getData();
                            tree[i].setData(tree[i].getRight().getData());
                            tree[i].getRight().setData(temp);
                            i = tree[i].getLeft().getIndex();
                        }
                    }

                }else{
                    if(tree[i].getData().hashCode() < tree[i].getLeft().getData().hashCode()){
                        Object temp = tree[i].getData();
                        tree[i].setData(tree[i].getLeft().getData());
                        tree[i].getLeft().setData(temp);
                        i = tree[i].getLeft().getIndex();
                    }
                }
            }else{

            }
            i--;
        }
        return tree;
    }

对二叉树进行调整,使得最大值放在最后一个节点,第二大值放在倒数第二个节点…以此类推

 public static void sortNode(Node[] tree){
        int i = tree.length-1;
        while(i > 0){
            Object temp = tree[i].getData();
            tree[i].setData(tree[0].getData());
            tree[0].setData(temp);
            /*将排好序的节点和它的双亲节点的父子关系置为null(双亲节点.setRight[Left](null)),
            如果不这么做,使用BigRootHeap(tree)再对树进行排序时依旧会把排好序的节点data计算在内,
            导致始终得不到一颗有序的树*/
            if(i % 2 == 0){
                tree[i].getParent().setRight(null);
            }else{
                tree[i].getParent().setLeft(null);
            }
            BigRootHeap(tree);
            i--;
        }
        //直接将排序内容输出
        for(int j= 0;j<tree.length;j++){
            System.out.print(tree[j].getData().toString()+" ");
        }
        System.out.println();
    }

运行结果

  public static void main(String[] args){
        Object[] arr = new Object[]{1,34,54,23,2,3433,12};
        sortNode(BigRootHeap(createTree(arr)));
    }

1 2 12 23 34 54 3433

新人第一次在csdn上写文章,有啥写的不对的地方或者需要改进烦请大家指出=-=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值