java之堆排序
直接上代码:
--------------------------------------------------------
package com.mylearn;
import java.util.*;
/**
* 本程序是进行堆排序 首先需要明白堆是一种特殊的完全二叉树,并且它的孩子结点永远小于父母结点 —— 基本思想:
* 堆排序是一种树形选择排序,是对直接排序算法的有效改进。堆的定义如下:具有n个元素的序列(h1,h2,…,hn),当且仅当满足(hi>=h2i,hi>=2i
* +1)或(hi<=h2i,hi<=2i+1)
* (i=1,2,…,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。
* 完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,
* 这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,
* 最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。
* 一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
*
* @author H
*
*/
public class DuiPaiXu
{
public static void main(String[] args) {
// 声明一个列表,存储数据
Integer[] list = { 1, 0, -2, 3, 5, 1, 2, 10, 11, 21, 3, 2 };
heapsort(list);
for (Integer element : list)
System.out.println(element);
}
/*
* 首先编写堆类 堆类用线性列表来存储数据
*
*/
private ArrayList
list = new ArrayList
();
public DuiPaiXu(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
public DuiPaiXu() {
}
public void add(E object) {
list.add(object);
int currentindex = list.size() - 1;
while (currentindex > 0) {
int parentindex = (currentindex - 1) / 2;
/*
* 如果父类结点小于子类结点,则将它们交换值 这个过程一直持续到父类结点不再小于子类结点为止
*/
if (list.get(parentindex).compareTo(list.get(currentindex)) < 0) {
E temp = list.get(currentindex);
list.set(currentindex, list.get(parentindex));
list.set(parentindex, temp);
} else
break;
currentindex = parentindex;// 把新加的数的下标更新
}
}
@SuppressWarnings("unchecked")
public E remove() {
if (list.size() == 0)
return null;
/*
* 基本思想是 remove()方法只能移除根处的元素 然后重新组建堆 首先把最后一个元素移到根处
* 然后将根与它的结点进行比较,若小于其子结点,则交换下移即可 直到下标最大为止
*/
E removedObject = list.get(0);
list.set(0, list.get(list.size() - 1));
list.remove(list.size() - 1);
int currentindex = 0;
while (currentindex < list.size()) {
int leftchildindex = 2 * currentindex + 1;// 左孩子
int rightchildindex = 2 * currentindex + 2;// 右孩子
if (leftchildindex >= list.size())
break;
/*
* 下面语句确定左边子结点与右边子结点的大小 以便将父结点与最大的子结点进行比较 进而确定是否执行交换动作
*/
int maxindex = leftchildindex;
if (rightchildindex < list.size()) {
if (list.get(maxindex).compareTo(list.get(rightchildindex)) < 0)
maxindex = rightchildindex;
}
/*
* 下面开始执行交换动作 若父结点比最大的子结点要小 则交换它们
*/
if (list.get(currentindex).compareTo(list.get(maxindex)) < 0) {
E temp = list.get(currentindex);
list.set(currentindex, list.get(maxindex));
list.set(maxindex, temp);
currentindex = maxindex;
}
/*
* 直到父结点不再小于最大的子结点为止
*/
else
break;
}
return removedObject;
}
public static
void heapsort(E[] list) {
DuiPaiXu
heap = new DuiPaiXu
(); for (int i = 0; i < list.length; i++) heap.add(list[i]); for (int i = list.length - 1; i >= 0; i--) list[i] = heap.remove(); } }