第六章 堆排序

以后尽量能用迭代就别用递归啊,递归只是让自己轻松了,但是却增加了电脑的负担。


package chap06_Heap_Sort;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;

public class SortAlorithms {
/**
* 返回当前下标下父节点的下标
*
* @param i
* @return
*/
protected static int parent(int i) {
if (i == 0)
return i;
return (i - 1) / 2;
}

/**
* 返回i的对应左子节点下标
*
* @param i
* @return
*/
protected static int left(int i) {
return 2 * i + 1;
}

/**
* 返回i对应右子节点下标
*
* @param i
* @return
*/
protected static int right(int i) {
return 2 * (i + 1);
}

/**
* 维护最大堆性质(递归方法实现) 容易内存溢出
*
* @param a
* @param i
*/
protected static void maxHeapify1(int[] a, int i, int SIZE) {
int l = left(i);
int r = right(i);
int tmp;
if (l < SIZE & r < SIZE) {
if (a[i] >= a[l] & a[i] >= a[r])
return;
else if (a[l] > a[r]) {
tmp = a[i];
a[i] = a[l];
a[l] = tmp;
i = l;
} else {
tmp = a[i];
a[i] = a[r];
a[r] = tmp;
i = r;
}
} else if (l < SIZE) {
if (a[i] < a[l]) {
tmp = a[i];
a[i] = a[l];
a[l] = tmp;
i = l;
}
} else {
return;
}
maxHeapify1(a, i, SIZE);
}

/**
* 重建最大堆,从i开始到size(不包含size索引)
*
* @param a
* @param i
* @param SIZE
*/
protected static void maxHeapify(int[] a, int i, int SIZE) {
int l = left(i);
int r = right(i);
int tmp;
while (l < SIZE & r < SIZE) {
if (a[i] >= a[l] & a[i] >= a[r])
return;
else if (a[l] > a[r]) {
tmp = a[i];
a[i] = a[l];
a[l] = tmp;
i = l;
} else {
tmp = a[i];
a[i] = a[r];
a[r] = tmp;
i = r;
}
l = left(i);
r = right(i);
}
if (l < SIZE) {
if (a[i] < a[l]) {
tmp = a[i];
a[i] = a[l];
a[l] = tmp;
i = l;
}
}
return;
}

/**
* 将数组a转换成最大堆,不要用递归方法,尽量用迭代方法实现
*
* @param a
*/
protected static void buildMaxHeap(int[] a) {
int n = a.length;

for (int i = n / 2; i >= 0; i--) {
maxHeapify1(a, i, n);
}
}

/**
* 堆排序
*
* @param n
*/
static void heapSort(int[] n) {
buildMaxHeap(n);
int l = n.length;
int size = l;
int tmp;
for (int i = l - 1; i > 0; i--) {
tmp = n[0];
n[0] = n[i];
n[i] = tmp;
size--;
maxHeapify(n, 0, size);
}
}

@Test
public void testName() throws Exception {
// int[] a = { 2, 5, 3, 7, 8, 12, 0, 2, 45, 32 };
int[] a = { 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 };
// buildMaxHeap(a);
// heapSort(a);
maxHeapify1(a, 0, 10);
System.out.println(Arrays.toString(a));
}
}

第六章 堆排序

时间: 2024-08-03 14:50:11

第六章 堆排序的相关文章

第六章 堆排序 6.5 优先队列

package chap06_Heap_Sort; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import org.junit.Test; /** * 优先队列,二叉堆数组实现,数组的size最好大一些,至少比里面的堆大一些,来实现堆的扩展(插入元素) * * @author xiaojintao * */ public class PriorityQueue {

算法导论第六章 堆排序

堆的时间复杂度是建O(n),时间复杂度为堆排序O(NLogN),细节如以下的算法看到: #include <iostream> using namespace std; void swap(int &i,int &j) { int temp=i; i=j; j=temp; } void shiftDown(int *A, int start,int len) { int temp=A[start]; int i=start; int j=2*i+1; while (j<l

第六章——堆排序

一 堆 堆给人的感觉是一个二叉树,但是其本质是一种数组对象,因为对堆进行操作的时候将堆视为一颗完全二叉树,树种每个节点与数组中的存放该节点值的那个元素对应.所以堆又称为二叉堆,堆与完全二叉树的对应关系如下图所示: 二叉堆可以分为两种形式:最大堆和最小堆.在这两种堆中,结点的值都要满足堆的性质. 在最大堆中,最大堆的性质是指除了根以外的所有结点i都要满足: A[PARENT(i)]>=A[i] 也就是说,某个结点的值至多与其父结点一样大.因为,堆中的最大元素存放在根结点中:并且,在任一子树中,该子

算法导论第六章堆排序(一)

现在来看, 堆的含义大概有两种,一种是数据结构,一种是在一些语言中所定义的“垃圾回收机制”,如Java,在书本上的开篇强调了这两者,并强调若非特殊说明,皆把堆看做是一种数据结构. (二叉)堆的定义: 1)它是一个数组,可以被看成是一棵近似的完全二叉树,树上的每一个节点看做是数组中的每一个元素. 2)堆分为最大堆和最小堆,最大堆中每一棵子树的父节点的值大于孩子节点,最小堆则相反. 3)表示堆的数组A包括两个属性:A.length和A.heap_size.前者是数组元素的个数,后者是堆元素的个数,h

算法导论 第六章 堆排序

http://blog.csdn.net/mishifangxiangdefeng/article/details/7662515 http://www.cnblogs.com/Jiajun/archive/2013/05/31/3110256.html 这里练习6.3-3看http://blog.csdn.net/sailing_lqh/article/details/7381893的比较好理解

算法导论笔记——第六七章 堆排序和快速排序

第六章 堆排序 最小堆和最大堆:近似的完全二叉树 A[parent(i)]<=A[i]或者A[parent(i)]>=A[i] 建堆复杂度O(n) 排序O(nlgn) 实际应用中,快速排序一般优于堆排序.可用于优先队列等. 在一个包含n个元素的堆中,所有优先队列的操作均可在O(lgn)时间内完成. 第七章 快速排序 与归并排序一样用分治思想 主元pivot可随机生成

算法导论 第6章 堆排序

堆数据结构实际上是一种数组对象,是以数组的形式存储的,但是它可以被视为一颗完全二叉树,因此又叫二叉堆.堆分为以下两种类型: 大顶堆:父结点的值不小于其子结点的值,堆顶元素最大 小顶堆:父结点的值不大于其子结点的值,堆顶元素最小 堆排序的时间复杂度跟合并排序一样,都是O(nlgn),但是合并排序不是原地排序(原地排序:在排序过程中,只有常数个元素是保存在数组以外的空间),合并排序的所有元素都被拷贝到另外的数组空间中去,而堆排序是一个原地排序算法. 1.在堆排序中,我们通常使用大顶堆来实现,由于堆在

算法导论 第6章 堆排序(简单选择排序、堆排序)

堆数据结构实际上是一种数组对象,是以数组的形式存储的,可是它能够被视为一颗全然二叉树,因此又叫二叉堆.堆分为下面两种类型: 大顶堆:父结点的值不小于其子结点的值,堆顶元素最大 小顶堆:父结点的值不大于其子结点的值,堆顶元素最小 堆排序的时间复杂度跟合并排序一样,都是O(nlgn),可是合并排序不是原地排序(原地排序:在排序过程中,仅仅有常数个元素是保存在数组以外的空间),合并排序的全部元素都被复制到另外的数组空间中去,而堆排序是一个原地排序算法. 1.在堆排序中,我们通常使用大顶堆来实现,因为堆

第六章 常见排序算法

上章回顾 二叉树的定义 树深度的定义 什么样的二叉树是满二叉树 中序遍历的规则 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git 第六章 第六章 常见排序算法 常见排序算法 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Algorith