java实现堆排序

最近开始学习排序的相关知识,计划以后每天都要整理一个排序的算法。

今天整理了堆排序的排序算法,起初自己并不了解堆排序的相关过程,在阅读了博客http://www.cnblogs.com/luchen927/archive/2012/03/08/2381446.html之后,才对这方面的知识有所了解,在看了此博客的指导之后,感觉他写的代码有点问题,所以就自己重新写了一个。

其中最需要注意的就是:

根据根结点i(i为数组中的下标)来计算其左右孩子的坐标时,left = i * 2 + 1, right = i * 2 + 2, 因为根节点是从数组0位置开始的。

import java.util.Arrays;

/**
 * 堆排序的介绍:
 * 堆排序对于记录数较少的文件并不提倡,但对n较大的文件还是很有效的。
 * 其最坏情况下的时间复杂度为:O(nlogn), 在最好情况下,时间复杂度为:O(1).
 * 堆排序是不稳定的排序。
 *
 *
 *
 *堆排序的具体过程:
 * 1 、首先从第一个非叶子节点开始,比较当前节点和其孩子节点,将最大的元素放在当前节点,交换当前节点和最大节点元素。
 * 2 、将当前元素前面所有的元素都进行1的过程,这样就生成了最大堆
 * 3 、将堆顶元素和最后一个元素交换,列表长度减1。由此无序区减1,有序区加1
 * 4 、剩余元素重新调整建堆
 * 5 、 继续3和4,直到所有元素都完成排序
 *
 *
 **/

public class HeapSort{

	public static void heapSort(int[] num){
		if(num == null) return;

		int len = num.length;

		buildHeap(num, len);

		/**每次将堆顶元素放到数组最后的位置*/
		while(len > 1){
			swap(num, len - 1, 0);
			len --;
			adjustHeap(num, len, 0);
		}
	}

	/**将一个无序的数组构建成一个大顶堆*/
	private static void buildHeap(int[] num, int len) {

		/**begin为最后一个根节点在数组中的下标*/
		int begin = len / 2 -1;

		/**依次遍历每一个根节点,通过调整,使每一个根节点都比它的孩子结点大*/
		for(int i = begin; i >= 0; i--){
			adjustHeap(num, len, i);
		}
	}

	/**调整根节点和孩子结点的位置,使其满足大顶堆*/
	private static void adjustHeap(int[] num, int len, int i) {
		/**获取下标为i的根节点的左孩子和右孩子在数组中的下标*/
		int leftChild = i * 2 + 1;
		int rightChild = i * 2 + 2;

		/**将本次调整的最大值下标暂时记为i*/
		int max = i;

		while(leftChild < len || rightChild < len){
			/**如果num[max]的左孩子num[leftChild]比max大,将leftChild暂存在max中*/
			if(leftChild < len && num[max] < num[leftChild]){
				max = leftChild;
			}

			/**如果num[max]的右孩子num[rightChild]比max大,将rightChild暂存在max中*/
			if(rightChild < len && num[max] < num[rightChild]){
				max = rightChild;
			}

			/**如果在前面的运算中,发生过赋值*/
			if(i != max){
				swap(num, max, i);

				i = max;
				leftChild = i * 2 + 1;
				rightChild = i * 2 + 2;
			}else{
				break;
			}
		}//while(leftChild < len || rightChild < len)
	}//private static void adjustHeap()

	/**将数组中num[x]和num[y]位置交换*/
	private static void swap(int[] num, int x, int y) {
		num[x] = num[x] ^ num[y];
		num[y] = num[x] ^ num[y];
		num[x] = num[x] ^ num[y];

	}

	public static void main(String[] args) {
		int[] num = {0, 9, 7, 0, 0, 6, -40, 200};
		HeapSort.heapSort(num);
		System.out.println(Arrays.toString(num));

	}
}

java实现堆排序,布布扣,bubuko.com

时间: 2024-11-08 01:55:55

java实现堆排序的相关文章

Java 实现堆排序

堆 堆排序和合并排序一样,是一种时间复杂度为O(nlgn)的算法,同时和插入排序一样,是一种就地排序算法(不需要额外的存储空间).堆排序需要用到一种被称为最大堆的数据结构,与java或者lisp的gc不一样,这里的堆是一种数据结构,他可以被视为一种完全二叉树,即树里面除了最后一层其他层都是填满的.也正是因为这样,树里面每个节点的子女和双亲节点的序号都可以根据当前节点的序号直接求出. Parent(i)=i/2 Left(i)=2*i Right(i)=2*i+1 如上图所示,1位置的子女节点分别

Java 小根堆排序

Counter类:计数器 IntPk中包含主键 public class Counter extends IntPK{     private int count;     public int getCount() {         return count;     }     public void setCount(int count) {         this.count = count;     } } MinHeap类:最小堆排序类 package com.ryx.incan

Java实现堆排序和计数排序

堆排序代码: import java.util.Arrays; /** * 思路:首先要知道大顶堆和小顶堆,数组就是一个堆,每个i节点的左右孩子是2i+1和2i+2 * 有了堆,将其堆化:从(n/2)-1个元素开始向下修复,将每个节点修复为小(大)顶堆 * 修复完成后,数组具有小(大)顶堆的性质 * 按序输出:小顶堆可以对数组逆序排序,每次交换堆顶和末尾元素,对堆顶进行向下修复,这样次小元素又到堆顶了 * * 时间复杂度:堆化:一半的元素修复,修复是单分支的,所以整体堆化为nlgn/2 * 排序

Java实现---堆排序 Heap Sort

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全

Java实现堆排序(大根堆)

堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素. 1. 若array[0,...,n-1]表示一颗完全二叉树的顺序存储模式,则双亲节点指针和孩子结点指针之间的内在关系如下: 任意一节点指针 i:父节点:i==0 ? null : (i-1)/2  左孩子:2*i + 1  右孩子:2*i + 2 2. 堆的定义:n个关键字序

算法(第四版)学习笔记之java实现堆排序

继上一篇实现基于堆的优先队列后,这次将利用上一次完成的基于堆的能够重复删除最大元素操作的优先队列来实现一种经典而优雅的排序算法,称之为堆排序. 堆排序可分为两个阶段: 1.构建堆:在堆的构建过程中,我们将原始数组重新组织安排进一个堆中: 2.下沉排序:从堆中按递减顺序取出所有元素并得到排序结果 具体的思想在下面的代码中有较为详细的注释: /** * * @author seabear * */ public class HeapSort { /** * 1.构造大根堆:与上一篇基于堆的优先队列相

java基础之:堆排序

最近做题目饱受打击,愈发觉得打好基础的重要性,于是乎,决心把基本的排序算法还有数组操作一一实现,目的在于一方面能够得到对JAVA基础的巩固,另一面在实现的过程中发现不足. 今天所实现的堆排序(最大堆)算法,最小堆大同小异.然后基于最大堆实现最大优先队列,最大优先队列可应用于作业调度,比如可将作业长度作为关键字值,实现最长作业优先:或者将作业优先权值作为关键字值,实现高优先权作业优先执行等等.最大堆排序算法结构如下图: 1 //:ThinkingInJava/com.mindview.fundam

Java实现排序算法之快速排序

一.综述 快速排序是交换排序中的一种,平均算法复杂度是O(nlogn),最坏O(n*n).下面用Java实现一个快速排序,并用注释的方式解释了思想和原理. 二.Java实现堆排序 三.结果检验 版权声明:本文为博主原创文章,未经博主允许不得转载.

Java实现排序算法之归并排序

一.综述 归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 算法描述 归并操作的过程如下: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 设定两个指针,最初位置分别为两个已经排序序列的起始位置 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针达到序列尾 将另一序列剩下的所有元素直接复制到合并序列尾