堆排序原理及java代码实现

堆排序的实现原理是将,数组元素,看做是位于一棵二叉树上的节点。

 

通过构建大根堆,需要使用父子指针,设置,左孩子和右孩子指针。设置初始的父亲指针指向二叉树的最后一个元素,

左孩子指针的下标应该为2*parent+1,右孩子指针下标 child+1

完成构建大根堆

交换堆顶堆底元素,并做减枝操作,并重复这个动作,直到长度为1

代码如下:

 public static void main(String[] args) {
        int[] num={5,7,4,2,0,3,1,6};
        for(int p=num.length -1; p>=0 ;p--){
            //完成构建大根堆
            Hasp(num,p,num.length);//父节点递减遍历
        }
        for (int i=num.length-1;i>0;i--){
            //将大根堆的堆顶节点和堆底节点交换
            int tmp=num[i];
            num[i]=num[0];
            num[0]=tmp;
            //之后的父指针从下标为0的节点开始遍历
            Hasp(num,0,i);
        }
        System.out.println(Arrays.toString(num)); 
}
public static void Hasp(int[] num,int parent,int length){
        //构建大根堆
        int temp=num[parent];//设置临时变量,存放父节点的值
        int child=2*parent+1;
        while(child<length){
            //如果孩子指针的长度超出了数组长度,就不执行操作,让父指针接着遍历
            int rchild=child+1;
            if (num[child]<num[rchild] &&rchild<length){
                //如果右孩子节点的值大于左孩子节点,让右孩子节点作为孩子节点
                child++;
            }
            if (temp>=num[child]){//如果临时节点中的值时大于孩子节点的值的,就结束循环
                break;
            }
            num[parent]=num[child];//将孩子节点的值给父节点
            parent=child;//父节点向下遍历指向孩子节点
            child=2*parent+1;
        }
        num[parent]=temp;//循环结束后,都需要将临时节点的值,在交给当前父指针指向的节点
    }

这里有一点是需要弄清楚的,否则是无法读懂代码的,就是在父指针向下遍历孩子节点的时候,当结束遍历后,按道理来说父指针应该是指向该子树的最后一个孩子节点,但是,结束一次Hasp程序后,我们需要的是,父指针在继续递减地往前走。

 在调用的时候,我们给Hasp传递的参数是p,他不是parent,在程序中,向下遍历的是父指针,但是当结束程序后,p的值还是之前的那个值,并在次基础上递减。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值