Java实现---堆排序 Heap Sort

堆排序快速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。

堆的定义

  n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆。

  情形1:k<= k2i 且k<= k2i+1 最小化堆小顶堆

  情形2:k>= k2i 且k>= k2i+1 (化堆大顶堆

  其中i=1,2,…,n/2向下取整;

若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。

  由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

堆的存储

  一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。

堆排序的实现

  实现堆排序需要解决两个问题:

    1.如何由一个无序序列建成一个堆?

    2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

  先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。

  我们称这个自堆顶至叶子的调整过程为“筛选”。

  从无序序列建立堆的过程就是一个反复“筛选”的过程。

示例代码:

package heapSort;

/**
 * 堆排序,采用顺序存储
 * 大根堆
 * @author 超超boy
 *
 */
public class HeapSort2 {
	int[] arr;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HeapSort2 heapSor = new HeapSort2();
		int[] arr = {7,23,45,9,40,73,12,49};  //0下标放的是数组长度,
	    heapSor.arr = arr;
		heapSor.heapSort(arr);

		for(int i=0;i<arr.length;i++)
			System.out.print(".."+arr[i]);
	}
	void heapAdjust(int[] arr,int s,int m){
		//已知arr[s...m]中记录的关键字除arr[s]之外均满足堆的定义,本函数调整arr[s]的关键字,使arr[s...m]成为一个最大堆
		int rc = arr[s]; //s是最后一个非叶子节点

		for(int j=2*s;j <= m;j*=2){
			if(j<m && arr[j]<arr[j+1])
				j++;  //j为key较大的下标
			if(rc >= arr[j]) break;
		     arr[s] = arr[j];  //上移到父节点
		     s=j;
		}
		arr[s]=rc;  //要放入的位置

	}

	void heapSort(int[] arr){
		//对顺序表进行堆排序
		for(int i=(arr.length-1)/2;i > 0;i--){//因为0没有使用,所以length-1
			heapAdjust(arr,i,arr.length-1);
		}
		System.out.println(".....................");

		outputArr(1);
		for(int i=arr.length-1; i>1; i--){
			int temp = arr[1];
			arr[1] = arr[i];
			arr[i] = temp;
			heapAdjust(arr,1,i-1);
		}
	}
	void outputArr(int i){

		if(i <= arr[0]){
			System.out.println(arr[i]);
			outputArr(i*2);  //左
			outputArr(i*2+1);  //右
		}
	}

}

  运行结果:

.....................
73
45
40
23
49
12
9
..7..9..12..23..40..45..49..73

堆排序分析

堆排序方法对记录数较少的文件并不值得提倡,但对n较大的文件还是很有效的。因为其运行时间主要耗费在建初始堆和调整建新堆时进行的反复“筛选”上。

  堆排序在最坏的情况下,其时间复杂度也为O(nlogn)。相对于快速排序来说,这是堆排序的最大优点。此外,堆排序仅需一个记录大小的供交换用的辅助存储空间。

时间: 2024-10-23 19:03:12

Java实现---堆排序 Heap Sort的相关文章

数据结构 - 堆排序(heap sort) 详解 及 代码(C++)

堆排序(heap sort) 详解 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包含两个步骤: 第一步: 是建立大顶堆(从大到小排序)或小顶堆(从小到大排序), 从下往上建立; 如建堆时, s是从大到小; 第二步: 是依次交换堆顶和堆底, 并把交换后的堆底输出, 只排列剩余的堆, 从上往下建立; 如构造时, s始终是1; 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: S

数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)

堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排序)或小顶堆(从小到大排序), 从下往上建立; 如建堆时, s是从大到小; 第二步: 是依次交换堆顶和堆底, 并把交换后的堆底输出, 仅仅排列剩余的堆, 从上往下建立; 如构造时, s始终是1; 堆排序(Heap Sort)的时间复杂度是O(nlogn), 最坏情况下也是如此. 而高速排序(Quic

经典排序算法 - 堆排序Heap sort

经典排序算法 - 堆排序Heap sort 堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么

堆排序 Heap Sort

堆排序是一种选择排序,其时间复杂度为O(nlogn). 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左

转载:堆排序 Heap Sort

堆排序是一种选择排序,其时间复杂度为O(nlogn). 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左

算法分析-堆排序 Heap Sort

堆排序的是集合了插入排序的单数组操作,又有归并排序的时间复杂度,完美的结合了2者的优点. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终

算法----堆排序(heap sort)

堆排序是利用堆进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,具体算法分析可以点击堆排序算法时间复杂度分析. 算法实现: 调整堆: void sort::sink(int* a, const int root, const int end) { int i=root; while(2*i +1 <= end) { int k = 2*i+1; if(k+1<=end && a[k]<a[k+1]) k++; if(a[k] < a[i]) break;

堆排序Heap sort

堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个“优秀”的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么是最大堆 堆中每个父节点的元素值都大于等于其孩子结点(

[Unity][Heap sort]用Unity动态演示堆排序的过程

[Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this heap sort demo to show how heap sort works recently. 效果图(Demo) 一图抵千言. A picture paints a thousand words. 您可以在此查看完整的动态GIF效果图.博客园里放不下这么大的GIF图. 链接:http://p