Java排序算法(五):堆排序

[算法说明]

堆排序是对简单选择排序的改进

简单选择排序是从n个记录中找出一个最小的记录,需要比较n-1次。但是这样的操作并没有把每一趟的比较结果保存下来,在后一趟的比较中,有许多比较在前一趟已经做过了,但由于前一趟排序时未保存这些比较结果,所以后一趟排序时又重复执行了这些比较操作,因而记录的比较次数较多。

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

[算法思想]

将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次最大值。如此反复执行,就能得到一个有序序列了。

[java实现]

public class HeapSort {

	public static void main(String[] args) {
		int[] arr = { 6, 5, 3, 1, 8, 7, 2, 4 };
		System.out.println("排序之前:");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}

		// 堆排序
		heapSort(arr);

		System.out.println();
		System.out.println("排序之后:");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}

	/**
	 * 堆排序
	 */
	private static void heapSort(int[] arr) {
		for (int i = arr.length / 2; i >= 0; i--){ // 将待排序的序列构建成一个大顶堆
			heapAdjust(arr, i, arr.length);
		}
		for (int i = arr.length - 1; i > 0; i--) { // 逐步将每个最大值的根节点与末尾元素交换,并且再调整其成为大顶堆
			swap(arr, 0, i); // 将堆顶记录和当前未经排序子序列的最后一个记录交换
			heapAdjust(arr, 0, i);
		}
	}

	private static void heapAdjust(int[] arr, int i, int n) {
		int child;
		int tmp;
		for (tmp = arr[i]; leftChild(i) < n; i = child) {
			child = leftChild(i);
			if (child != n - 1 && arr[child] < arr[child + 1]) {
				child++;
			}
			if (tmp < arr[child]) {
				arr[i] = arr[child];
			} else {
				break;
			}
		}
		arr[i] = tmp;
	}

	private static int leftChild(int i) {
		return 2 * i + 1;
	}

	private static void swap(int[] arr, int index1, int index2) {
		int tmp = arr[index1];
		arr[index1] = arr[index2];
		arr[index2] = tmp;
	}
}

[算法总结]

堆排序时间复杂度:O(nlogn)

堆排序对原始记录的排序状态并不敏感,其在性能上要远远好过于冒泡、简单选择、直接插入排序。

时间: 2024-12-25 11:36:36

Java排序算法(五):堆排序的相关文章

Java排序算法 - 堆排序的代码

把内容过程中比较重要的一些内容片段做个备份,如下的资料是关于Java排序算法 - 堆排序的内容. import java.util.Arrays; public class HeapSort { int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; public HeapSort(){ heapSort(a); } public void heapSort(int[

Java排序算法(一)

Java排序算法(一) 一.排序的基本概念和分类 1.1排序的定义 在<大话数据结构>中,排序定义为,假设含有n个记录的序列为{r1,r2,...,rn},其相应的关键字{k1,k2,...,kn},需确定1,2...n的一种排列p1,p2...pn,是其相应的关键字满足Kp1<=Kp2<=...<=Kpn(非递减或非递增)关键,即使得序列称为一个按关键字有序的序列{rp1,rp2...rp3},这样的操作称为排序. 1.2排序的稳定性 假设ki=kj(1<=i<

Java排序算法-Java入门|Java基础课程

Java 排序算法 1. 课程目标 排序是任何语言都会使用到的功能之一,然成果排序的算法有很多,对空间的要求及其时间效率也不尽相同. 本文章以Java语言示例,通过对空间要求.时间效率要求,来对比各种排序算法的使用场景 2.适用对象 Java语言初学者 Java算法爱好者 3.相关概念 3.1 排序概念 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 3.2 排序算法 排序算法,就是如何使得记录按照要求排列的方法. 排序算法在很多领域得到相当地重视,尤其是在

排序算法系列——堆排序

记录学习点滴,菜鸟成长记 堆排序引入了另一种算法设计技巧:使用一种我们称之为“堆”的数据结构来进行数据管理. 堆排序算是真正意义上的利用数据结构来求解数组排序的方法. “插入排序”和“归并排序”可以看做是一种“计算机体力活”,体现的思想更多的是去模拟最简单的人类思维,比如插入排序过程中的比较,归并中子问题合并时的比较. “堆排序”可以看做是“计算机脑力活”,他利用了一种结构化的语言来表达,这种结构化带来一些性质,比如左右孩子.比[堆大小的一半向下取整]大的下标都是叶节点不需要维护其最大堆性质等.

java排序算法(六):直接插入排序

java排序算法(六):直接插入排序 直接插入排序的基本操作就是将待的数据元素按其关键字的大小插入到前面的有序序列中 直接插入排序时间效率并不高,如果在最坏的情况下,所有元素的比较次数的总和为(0+1..n-1)= o(n^2).其他情况下也要考虑移动元素的次数.故时间复杂度是o(n^2) 直接插入空间效率很好,只需要一个缓存数据单元,也就是说空间复杂度是o(1) 直接插入排序是稳定的 直接插入排序在数据以有一定顺序的情况下,效率较好.但如果数据无规则,则需要移动大量的数据.其效率就和冒泡排序和

Java排序算法总结

稳定排序:* 泡沫排序(bubble sort) — O(n²)* 插入排序 (insertion sort)— O(n²)* 桶排序 (bucket sort)— O(n); 需要 O(k) 额外空间* 计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外空间* 合并排序 (merge sort)— O(n log n); 需要 O(n) 额外空间* 二叉排序树排序 (Binary tree sort) — O(n log n)期望时间; O(n²)最坏时间;

(转)java 排序算法

排序算法汇总(java实现,附源代码) 整理系统的时候发现了原来写的各种算法的总结,看了一下,大吃一惊,那时候的我还如此用心,具体的算法,有的已经模糊甚至忘记了,看的时候就把内容整理出来,顺便在熟悉一下,以后需要的时候就可以直接过来摘抄了.下面是总结的几个常用的排序算法: 插入排序 快速排序 冒泡排序 堆排序 计数排序 桶排序 可能大家对插入排序,快速排序,冒泡排序比较常用,在满足需求的时候也简单一些,下面逐一说一下每个算法的实现方式,不保证是写的最有效率的,但是能保证的是,各种算法的中心思想是

Java排序算法之选择排序

一.算法原理 简单选择排序的基本思想:给定数组:int[] arr={里面n个数据}:第1趟排序,在待排序数据arr[1]~arr[n-1]中选出最小的数据,将它与arrr[0]交换:第2趟,在待排序数据arr[2]~arr[n-1]中选出最小的数据,将它与r[1]交换:以此类推,第i趟在待排序数据arr[i]~arr[n-1]中选出最小的数据,将它与r[i-1]交换,直到全部排序完成. 二.算法举例 数组 int[] arr={5,2,8,4,9,1}; -------------------

浅入浅出 Java 排序算法

Java String 源码的排序算法 一.前言 Q:什么是选择问题? 选择问题,是假设一组 N 个数,要确定其中第 K 个最大值者.比如 A 与 B 对象需要哪个更大?又比如:要考虑从一些数组中找出最大项? 解决选择问题,需要对象有个能力,即比较任意两个对象,并确定哪个大,哪个小或者相等.找出最大项问题的解决方法,只要依次用对象的比较(Comparable)能力,循环对象列表,一次就能解决. 那么 JDK 源码如何实现比较(Comparable)能力的呢? 二.java.lang.Compar