排序算法___堆排序

左手的ㄟ右手 2021-12-14 02:13 423阅读 0赞

/**
* 堆排序:Java
*
* @author skywang
* @date 2014/03/11
*/

public class HeapSort {

/*
* (最大)堆的向下调整算法
*
* 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
* 其中,N为数组下标索引值,如数组中第1个数对应的N为0。
*
* 参数说明:
* a — 待排序的数组
* start — 被下调节点的起始位置(一般为0,表示从第1个开始)
* end — 截至范围(一般为数组中最后一个元素的索引)
*/
public static void maxHeapDown(int[] a, int start, int end) {
int c = start; // 当前(current)节点的位置
int l = 2*c + 1; // 左(left)孩子的位置
int tmp = a[c]; // 当前(current)节点的大小

for (; l <= end; c=l,l=2*l+1) {
// “l”是左孩子,”l+1”是右孩子
if ( l < end && a[l] < a[l+1])
l++; // 左右两孩子中选择较大者,即m_heap[l+1]
if (tmp >= a[l])
break; // 调整结束
else { // 交换值
a[c] = a[l];
a[l]= tmp;
}
}
}

/*
* 堆排序(从小到大)
*
* 参数说明:
* a — 待排序的数组
* n — 数组的长度
*/
public static void heapSortAsc(int[] a, int n) {
int i,tmp;

// 从(n/2-1) —> 0逐次遍历。遍历之后,得到的数组实际上是一个(最大)二叉堆。
for (i = n / 2 - 1; i >= 0; i—)
maxHeapDown(a, i, n-1);

// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (i = n - 1; i > 0; i—) {
// 交换a[0]和a[i]。交换后,a[i]是a[0…i]中最大的。
tmp = a[0];
a[0] = a[i];
a[i] = tmp;
// 调整a[0…i-1],使得a[0…i-1]仍然是一个最大堆。
// 即,保证a[i-1]是a[0…i-1]中的最大值。
maxHeapDown(a, 0, i-1);
}
}

/*
* (最小)堆的向下调整算法
*
* 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
* 其中,N为数组下标索引值,如数组中第1个数对应的N为0。
*
* 参数说明:
* a — 待排序的数组
* start — 被下调节点的起始位置(一般为0,表示从第1个开始)
* end — 截至范围(一般为数组中最后一个元素的索引)
*/
public static void minHeapDown(int[] a, int start, int end) {
int c = start; // 当前(current)节点的位置
int l = 2*c + 1; // 左(left)孩子的位置
int tmp = a[c]; // 当前(current)节点的大小

for (; l <= end; c=l,l=2*l+1) {
// “l”是左孩子,”l+1”是右孩子
if ( l < end && a[l] > a[l+1])
l++; // 左右两孩子中选择较小者
if (tmp <= a[l])
break; // 调整结束
else { // 交换值
a[c] = a[l];
a[l]= tmp;
}
}
}

/*
* 堆排序(从大到小)
*
* 参数说明:
* a — 待排序的数组
* n — 数组的长度
*/
public static void heapSortDesc(int[] a, int n) {
int i,tmp;

// 从(n/2-1) —> 0逐次遍历每。遍历之后,得到的数组实际上是一个最小堆。
for (i = n / 2 - 1; i >= 0; i—)
minHeapDown(a, i, n-1);

// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (i = n - 1; i > 0; i—) {
// 交换a[0]和a[i]。交换后,a[i]是a[0…i]中最小的。
tmp = a[0];
a[0] = a[i];
a[i] = tmp;
// 调整a[0…i-1],使得a[0…i-1]仍然是一个最小堆。
// 即,保证a[i-1]是a[0…i-1]中的最小值。
minHeapDown(a, 0, i-1);
}
}

public static void main(String[] args) {
int i;
int a[] = {20,30,90,40,70,110,60,10,100,50,80};

System.out.printf(“before sort:”);
for (i=0; i<a.length; i++)
System.out.printf(“%d “, a[i]);
System.out.printf(“\n”);

heapSortAsc(a, a.length); // 升序排列
//heapSortDesc(a, a.length); // 降序排列

System.out.printf(“after sort:”);
for (i=0; i<a.length; i++)
System.out.printf(“%d “, a[i]);
System.out.printf(“\n”);
}
}

转载于:https://www.cnblogs.com/smallfa/p/11133126.html

发表评论

表情:
评论列表 (有 0 条评论,423人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法——排序

    排序算法——堆排序 > 堆排序是利用堆这种数据结构所设计的一种排序算法。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点

    相关 排序算法-排序

    堆是一个完全二叉树 堆排序是指利用堆这种数据结构所设计的一种排序算法 大顶堆:每个结点的值都大于或等于其左右孩子结点的值 arr\[i\] >= arr\[2i+1

    相关 排序算法-排序

    堆排序算法是建立在堆这种数据结构的基础上,其实堆听着很高端,其实很简单,就是一个二叉树,但是又特殊条件,就是其父节点比孩子节点都大(或都小)的堆称为最大堆(最小堆),瞬间感觉很

    相关 排序算法——排序

    前言 对于推排序它像合并排序而不像插入排序,堆排序的运行时间为O(nlogn)。像插入排序而不像合并排序,它是一种原地排序算法:在任何时候,数组中只有常数和元素存储在输入

    相关 排序算法排序

    一、前言     堆排序是一种选择排序。     选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。 ----

    相关 排序算法排序

      相关博客: [排序算法:冒泡排序、插入排序、选择排序、希尔排序][Link 1] [排序算法:归并排序、快速排序][Link 2] [排序算法:桶排序、计数排序、基

    相关 排序算法---排序

    二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二