zoukankan      html  css  js  c++  java
  • 堆排序

    堆排序:O(nlogn)

    堆排序实际上是利用堆的性质来进行排序的,要知道堆排序的原理我们首先一定要知道什么是堆。 

    堆的定义: 

    堆实际上是一棵完全二叉树。 

    堆满足两个性质

    1、堆的每一个父节点都大于(或小于)其子节点; 

    2、堆的每个左子树和右子树也是一个堆。 

    堆的分类: 

    堆分为两类: 

    1、最大堆(大顶堆):堆的每个父节点都大于其孩子节点; 

    2、最小堆(小顶堆):堆的每个父节点都小于其孩子节点; 

       

    堆的存储: 

    一般都用数组来表示堆,i结点的父结点下标就为(i 1) / 2。它的左右子结点下标分别为2 * i + 12 * i + 2。如下图所示: 

       

    堆排序: 

    由上面的介绍我们可以看出堆的第一个元素要么是最大值(大顶堆),要么是最小值(小顶堆),这样在排序的时候(假设共n个节点),直接将第一个元素和最后一个元素进行交换,然后从第一个元素开始进行向下调整至第n-1个元素。所以,如果需要升序,就建一个大堆,需要降序,就建一个小堆。 

    堆排序的步骤分为三步

    1、建堆(升序建大堆,降序建小堆); 

    2、交换数据; 

    3、向下调整。 

    假设我们现在要对数组arr[]={8,5,0,3,7,1,2}进行排序(降序): 

    首先要先建小堆: 

    堆建好了下来就要开始排序了: 

    现在这个数组就已经是有序的了。 

    下面给出代码:

    public class HeapSort {
        public static void main(String []args){
            int []arr = {9,8,7,6,5,4,3,2,1};
            sort(arr);
            System.out.println(Arrays.toString(arr));
        }
        public static void sort(int []arr){
            //1.构建大顶堆
            for(int i=arr.length/2-1;i>=0;i--){
                //从第一个非叶子结点从下至上,从右至左调整结构
                adjustHeap(arr,i,arr.length);
            }
            //2.调整堆结构+交换堆顶元素与末尾元素
            for(int j=arr.length-1;j>0;j--){
                swap(arr,0,j);//将堆顶元素与末尾元素进行交换
                adjustHeap(arr,0,j);//重新对堆进行调整
            }
    
        }
    
        /**
         * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
         * @param arr
         * @param i
         * @param length
         */
        public static void adjustHeap(int []arr,int i,int length){
            int temp = arr[i];//先取出当前元素i
            for(int k=i*2+1;k<length;k=k*2+1){//从i结点的左子结点开始,也就是2i+1处开始
                if(k+1<length && arr[k]<arr[k+1]){//如果左子结点小于右子结点,k指向右子结点
                    k++;
                }
                if(arr[k] >temp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                    arr[i] = arr[k];
                    i = k;
                }else{
                    break;
                }
            }
            arr[i] = temp;//将temp值放到最终的位置
        }
    
        /**
         * 交换元素
         * @param arr
         * @param a
         * @param b
         */
        public static void swap(int []arr,int a ,int b){
            int temp=arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }
    

      

  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/shuzhiwei/p/11250917.html
Copyright © 2011-2022 走看看