堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

面试题:大(小)顶堆

将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)

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

 1、大顶堆(升序)

    public static void SortByMaxHeap(int[] a,int size){
        //1.构建大顶堆
        justMaxHeap(a,size);
        //2.调整堆结构+交换堆顶元素与末尾元素
        for(int j=a.length-1;j>0;j--){
            //将堆顶元素与末尾元素进行交换
            int temp=a[0];
            a[0] = a[j];
            a[j] = temp;
            justMaxHeap(a,j);//重新对堆进行调整
        }

        //打印
        for(int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }

    /**
     * 调整堆结构
     * @param a 数组
     * @param size 要调整数组的大小
     */
    public static void justMaxHeap(int[] a,int size){

        for(int i=(size/2)-1;i>=0;i--){
            if(2*(i+1)>=size){//偶数,没有右子树节点
                if(a[i]<a[2*i+1]){//只比较左子树
                    int temp=a[i];
                    a[i]=a[2*i+1];
                    a[2*i+1]=temp;
                }
            }else{
                if(a[i]<a[2*i+1]||a[i]<a[2*(i+1)]){
                    if(a[2*i+1]>=a[2*(i+1)]){//比较左右子树大小
                        int temp=a[i];
                        a[i]=a[2*i+1];
                        a[2*i+1]=temp;
                    }else{
                        int temp=a[i];
                        a[i]=a[2*(i+1)];
                        a[2*(i+1)]=temp;
                    }
                }
            }
        }
    }

 2、小顶堆(降序)

    public static void SortByMinHeap(int[] a,int size){
        //1.构建小顶堆
        justMinHeap(a,size);
        //2.调整堆结构+交换堆顶元素与末尾元素
        for(int j=a.length-1;j>0;j--){
            //将堆顶元素与末尾元素进行交换
            int temp=a[0];
            a[0] = a[j];
            a[j] = temp;
            justMinHeap(a,j);//重新对堆进行调整
        }

        //打印
        for(int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }

    public static void justMinHeap(int[] a,int size){
        for(int j=size/2-1;j>=0;j--){
            if(2*(j+1)>=size){
                if(a[2*j+1]<a[j]){
                    int temp=a[j];
                    a[j]=a[2*j+1];
                    a[2*j+1]=temp;
                }
            }else{
                if(a[2*j+1]<a[j]||a[2*(j+1)]<a[j]){
                    if(a[2*j+1]<a[2*(j+1)]){
                        int temp=a[j];
                        a[j]=a[2*j+1];
                        a[2*j+1]=temp;
                    }else{
                        int temp=a[j];
                        a[j]=a[2*(j+1)];
                        a[2*(j+1)]=temp;
                    }
                }
            }
        }
    }

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-14
  • 2021-10-15
  • 2022-12-23
  • 2022-03-06
猜你喜欢
  • 2021-08-19
  • 2021-07-31
  • 2021-11-21
  • 2021-12-30
  • 2021-09-03
  • 2022-12-23
相关资源
相似解决方案