您的位置:首页 > 其它

算法导论:堆排序

2016-04-22 21:43 330 查看

堆是一个数组,它可以被看成一个近似的完全二叉树,树上的每一个结点对应数组中的一个元素。除去最底层外,该树是完全充满的,而且从左到右填充。

用数组A表示堆,从数组第1个元素开始,数组中第i(1<=i <=n)个元素,其父结点,左孩子,右孩子的下标如下

// 父结点
public  int parent( int i){
return i/2;
}
// 左孩子
public int left(int i){
return 2*i;
}
// 右孩子
public int right(int i){
return 2*i+1;
}


当数组起始下标是0的时候,其父结点,左右孩子结点如下

// 父结点
public  int parent( int i){
return (i-1)/2;
}
// 左孩子
public int left(int i){
return 2*i+1;
}
// 右孩子
public int right(int i){
return 2*i+2;
}


堆可以分为大顶堆和小顶堆

大顶堆:结点 i 的值 都大于其左右孩子结点的值

小顶堆:结点 i 的值 都小于其左右孩子结点的值

二叉树的形式与数组形式表达堆之间元素的关系

package heapSort;

class heap{
/**
* 堆排序 升序
* @param A
* @param n
*/
public void heap_sort(int[] A,int n){
build_max_heap(A,n);
for(int i = n;i>=2;i--){
swap(A,i,1);
max_heapify(A,i-1,1);
}
}
/**
* 建立大顶堆
* @param A
* @param n
*/
public void build_max_heap(int[] A,int n){
for(int i = n/2;i>=1;i--){
max_heapify(A,n,i);
}
}
/**
* 调整堆元素
* @param A 数组存放堆
* @param n 数组的数量 从 1 - n 开始
* @param i 需要调整的堆 元素 位置
*/
public void max_heapify1(int[] A ,int n,int i){
int l = -1;
int r = -1;
int largest = -1;
while(true){
l = left(i);
r = right(i);
if(l<=n && A[l] > A[i])
largest = l;
else
largest = i;
if(r <=n && A[r] > A[largest])
largest = r;
if(largest!=i){
swap(A,largest,i);
//更新i 的值相当的递归调用
i = largest;
// 相等 对左右子树不影响
}else{
break;
}
}
}
/**
* 调整堆元素
* @param A
* @param n
* @param i
*/
public void max_heapify(int[] A ,int n,int i){
// 左孩子结点
int l = left(i);
// 右孩子结点
int r = right(i);
// 最大结点下标
int largest = -1;
// 与左孩子判断
if(l<= n && A[l] > A[i])
largest = l;
else
largest = i;
// 与右孩子判断
if(r <=n && A[r] > A[largest])
largest = r;
// i 结点不是最大值maxId 和i 结点进行交换
if(largest != i ){
swap(A,largest,i);
max_heapify(A,n,largest);

}
}
/**
* 交换
* @param A
* @param l
* @param r
*/
public void swap(int [] A,int l,int r){
int tmp = A[l];
A[l] = A[r];
A[r] = tmp;
}
// 父结点
public  int parent( int i){
return i/2;
}
// 左孩子
public int left(int i){
return 2*i;
}
// 右孩子
public int right(int i){
return 2*i+1;
}
}
public class heapSort {
public static void main(String[] args) {
heap h = new heap();
// 第一个元素不考虑
int[] A = new int[]{-1,4,1,3,2,16,9,10,14,8,7};
int n = A.length-1;
//h.build_max_heap(A, n);
//printA(A);
//16 14 10 8 7 9 3 2 4 1
//16 14 10 8 7 9 3 2 4 1
h.heap_sort(A, n);
System.out.println();
printA(A);
}
public static void printA(int[] A){
for(int i:A){
System.out.print(i+" ");
}
}

}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: