zoukankan      html  css  js  c++  java
  • 【算法】堆排序

    堆排序

    上一篇博客讲了堆这种数据结构,它提供了一种接口getMax接口,好消息是获得最大值的时间复杂度仅仅为O(1),删除最大值delMax也仅仅需要O(lgn)的时间(删除后需要调整至满足堆的性质需要O(lgn)),因此联想到之前的选择排序算法,每次从剩下的未排序元素中找到极值元素,将其放入对应的位置。
    由于一般的选择排序在寻找最大值时需要遍历数组,遍历数组的复杂度为O(n),因此造成了时间的浪费,如若将待排序的数组进行一系列整理,例如将其整理成有特点的堆这种数据结构。那么我们有理由相信,能将选择排序的时间复杂度降低到O(nlgn)

    堆排序算法

    具体的堆排序算法如下,很容易理解

    HEAP-SORT(A)
    	// 利用数组A建最大堆
    	CREATE-HEAP(A)
    	for i= n-1 to 1
    		exchange A[0] A[i]
    		heap.size=heap.size-1;
    		// 由于交换可能会导致不满足堆的有序性,需要调整:下滤
    		Adjust(A,0)
    于是在Heap类中添加一个排序的方法
    public void heapSort(int[] heapArr) {
    		createHeapFloyd(heapArr);// 下标为0----n-1中保存着一个最大堆
    		for (int i = n - 1; i >= 1; i--) {
    			swap(heapArray, 0, i);
    			n--;
    			// 调整新的堆的顺序性
    			percolateDown(0);
    		}
    	}
    当调用heapSort后里面的堆已经被排好序了。然而这样还不够直接,如果将建堆时的操作改成
    public void createHeapFloyd(int[] heapArr) {
    //		System.arraycopy(heapArr, 0, heapArray, 0, heapArr.length);
    		heapArray = heapArr;
    		n = heapArr.length;
    		for (int i = (n - 1) >> 1; i >= 0; i--) {
    			percolateDown(i);
    		}
    	}

    即直接将待排序的数组赋给堆中维护的数组,性能更好。


    堆排序的性能

    这样调用堆排序后,数组已经有序,并且还不需要额外的内存空间,除了交换产生固定的空间消耗以外。即空间复杂度为O(1)

    堆排序是一种不稳定的排序算法,这是显然的,因为如果找到未排序部分的元素会和后面的交换,已排序部分的指针前移,再次有一个相同元素会放在前面,故而和原始顺序相反。


    测试

    public static void main(String[] args) {
    		Heap heap = new Heap(100);
    		int arr[] = new int[]{10,5,13,8,6,78,4,6};
    		heap.heapSort(arr);
    		for (int i : arr) {
    			System.out.print(i + "  ");
    		}
    	}

    输出序列为

    4  5  6  6  8  10  13  78  
  • 相关阅读:
    linux网络编程之socket编程(十四)
    linux网络编程之socket编程(十三)
    linux网络编程之socket编程(十二)
    linux网络编程之socket编程(十一)
    linux网络编程之socket编程(十)
    android:duplicateParentState属性使用场景
    python中操作mysql
    常用python包(依赖)Ubuntu下
    正则匹配汉字文字
    python 使用set对列表去重,并保持列表原来顺序
  • 原文地址:https://www.cnblogs.com/qhyuan1992/p/5385282.html
Copyright © 2011-2022 走看看