signed

QiShunwang

“诚信为本、客户至上”

堆排序-heapSort

2021/6/3 14:35:06   来源:

一、堆排序简介

堆排序基本介绍
1)堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。
2)堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。
3)每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

堆排序的基本思想:
1)将待排序序列构造成一个大顶堆
2)此时, 整个序列的最大值就是堆顶的根节点。
3)将其与末尾元素进行交换,此时末尾就为最大值。
4)然后将剩余n-1个元素重新构造成一个堆, 这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.

二、代码实现

在这里插入图片描述

package sort;

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args){

        int[] arr={8,2,6,3,9,5,1};
        heapSort(arr);


    }

    //定义堆排序的方法
    public static void heapSort(int[] arr){
        //定义临时变量,用于大顶堆排序时的交换
        int temp =0;

        System.out.println("待排序数组:"+Arrays.toString(arr));


        //分步完成
        /*
        adjustHeap(arr,1,arr.length);
        System.out.println("第一次:"+ Arrays.toString(arr));

        adjustHeap(arr,2,arr.length);
        System.out.println("第二次:"+ Arrays.toString(arr));

        adjustHeap(arr,0,arr.length);
        System.out.println("第三次:"+ Arrays.toString(arr));
         */


        //循环完成排序
        for (int i = arr.length/2-1;i>=0;i--){
            adjustHeap(arr,i,arr.length);
            System.out.println("调整大顶堆过程中...:"+ Arrays.toString(arr));
        }
        System.out.println("此时已经将数组调整为大顶堆!!!");

        for (int j=arr.length-1;j>0;j--){
            temp =arr[j];
            arr[j] =arr[0];
            arr[0] =temp;
            adjustHeap(arr,0,j);//每交换一次,再次调整为大顶堆,只不过下次无序
        }

        System.out.println("堆排序完成~~"+Arrays.toString(arr));

    }


    //定义一个方法,用于将顺序存储的数组(二叉树),调整为一个大顶堆
    //arr:传进来的无序数组、i:数组中对应非叶子节点的下标、length:没调整一次会变化
    public static void adjustHeap(int[] arr,int i,int length){
        //定义一个临时变量temp,存放当前非叶子节点arr[i]的值
        int temp =arr[i];
        for (int k =2*i+1;k<length;k=2*k+1){
            if (arr[k] < arr[k+1] && k+1 < length){//右子节点大于左子节点
                k++;//k指向右子节点
            }
            if(arr[k]>temp){//子节点大于父节点
                arr[i]=arr[k];
                i=k;
            }else{
                break;
            }
        }
        //循环目的是为了寻找最大值放在i为父节点的树的最大值,所以循环结束后,已经将索引为i的父节点的最大值放在了该树的顶部(局部)
        arr[i]=temp;
    }

}

结果截图
在这里插入图片描述