数据结构之堆排序

一、基本思想
在这里插入图片描述
在这里插入图片描述
二、代码

package com.ws.排序.堆排序;

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args) {
        //将数组进行升序排序
        int arr[]={4,6,8,5,9};
        duipai(arr);
    }

    //堆排序
    public static void duipai(int arr[]){
        int temp;
        System.out.println("堆排序!");

//        //分布完成
//        tiaodadingdui(arr,1,arr.length);
//        System.out.println("第一次"+ Arrays.toString(arr));// 4 9 8 5 6
//
//        tiaodadingdui(arr,0,arr.length);
//        System.out.println("第二次"+Arrays.toString(arr));//9 6 8 5 4

        //①将无序调整成一个堆
        for (int i=arr.length/2-1;i>=0;i--){//有子节点的树
            tiaodadingdui(arr,i,arr.length);
        }

        //②堆顶元素沉到末尾   一直循环,得到有序

        for (int j =arr.length-1;j>0;j--){
            //交换
            temp=arr[j];
            arr[j]=arr[0];
            arr[0]=temp;
            //重新调整结构,堆
            tiaodadingdui(arr,0,j);
        }

        System.out.println(Arrays.toString(arr));
    }


    //将一个数组(二叉树)调整为一个大顶堆
    /**
     *功能: 完成将以i为根节点的树调整成大顶堆
     * 比如 i=1  [4 6 8 5 9] => [4,9,8,5,6]
     * 从i=1到i=0  从下到上,从左到右
     * @param arr 待调整的数组
     * @param i  表示非叶子节点在数组中的索引
     * @param length 对多少个数进行调整  逐渐减少
     * 三个当中找最大,把最大的放到堆顶
     */
    public static void tiaodadingdui(int arr[],int i,int length){

        int temp=arr[i];//保存当前元素值
        //开始调整
        /**
         * k=i*2+1是当前节点i的左子节点
         * k=k*2+1是当前节点下一个节点的左子节点
         */
        for (int k=i*2+1;k<length;k=k*2+1){
            if (k+1<length && arr[k]<arr[k+1]){// 当前比较的是在个数限定范围之内 左子节点小于右子节点
                k++;//k指向右子节点  大的数
            }
            if (arr[k]>temp){//大的数节点大于父节点
                arr[i]=arr[k];//子节点上移父节点(覆盖)
                i=k;//下一次循环比较 i的位置下沉
            }else {
                break;
            }
        }
        //结束后  局部以i为顶的树是大顶堆
        arr[i]=temp;//将原来的顶放到新位置
    }
}

堆排序!
[4, 5, 6, 8, 9]

大数据测试:

package com.ws.排序.堆排序;

import java.text.SimpleDateFormat;
import java.util.Date;

public class HeapSorts {
    public static void main(String[] args) {
        //将数组进行升序排序
        System.out.println("########大数据排序80000########");
        int[] a=new int[80000];
        for (int i=0;i<80000;i++){
            a[i]=(int)(Math.random()*8000000);
        }
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String data=format.format(date);
        System.out.println("排序前时间="+data);
        //排序
        duipai(a);
        Date date1=new Date();
        String data2=format.format(date1);
        System.out.println("排序后的时间="+data2);
    }

    //堆排序
    public static void duipai(int arr[]){
        int temp;

//        //分布完成
//        tiaodadingdui(arr,1,arr.length);
//        System.out.println("第一次"+ Arrays.toString(arr));// 4 9 8 5 6
//
//        tiaodadingdui(arr,0,arr.length);
//        System.out.println("第二次"+Arrays.toString(arr));//9 6 8 5 4

        //①将无序调整成一个堆
        for (int i=arr.length/2-1;i>=0;i--){//有子节点的树
            tiaodadingdui(arr,i,arr.length);
        }

        //②堆顶元素沉到末尾   一直循环,得到有序

        for (int j =arr.length-1;j>0;j--){
            //交换
            temp=arr[j];
            arr[j]=arr[0];
            arr[0]=temp;
            //重新调整结构,堆
            tiaodadingdui(arr,0,j);
        }
    }


    //将一个数组(二叉树)调整为一个大顶堆
    /**
     *功能: 完成将以i为根节点的树调整成大顶堆
     * 比如 i=1  [4 6 8 5 9] => [4,9,8,5,6]
     * 从i=1到i=0  从下到上,从左到右
     * @param arr 待调整的数组
     * @param i  表示非叶子节点在数组中的索引
     * @param length 对多少个数进行调整  逐渐减少
     * 三个当中找最大,把最大的放到堆顶
     */
    public static void tiaodadingdui(int arr[],int i,int length){

        int temp=arr[i];//保存当前元素值
        //开始调整
        /**
         * k=i*2+1是当前节点i的左子节点
         * k=k*2+1是当前节点下一个节点的左子节点
         */
        for (int k=i*2+1;k<length;k=k*2+1){
            if (k+1<length && arr[k]<arr[k+1]){// 当前比较的是在个数限定范围之内 左子节点小于右子节点
                k++;//k指向右子节点  大的数
            }
            if (arr[k]>temp){//大的数节点大于父节点
                arr[i]=arr[k];//子节点上移父节点(覆盖)
                i=k;//下一次循环比较 i的位置下沉
            }else {
                break;
            }
        }
        //结束后  局部以i为顶的树是大顶堆
        arr[i]=temp;//将原来的顶放到新位置
    }
}

########大数据排序80000########
排序前时间=2021-04-21 09:39:57
排序后的时间=2021-04-21 09:39:57
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值