您的位置:首页 > 其它

堆排序

2012-06-08 21:08 211 查看
数据结构——堆排序

堆排序总结

堆排序思想:最大堆的堆顶元素是全部数据中的最大值,输出这个值

。再将剩余元素整理成新的最大堆,此时堆顶元素又是剩余元素

的最大值,再输出这个值。继续这个过程,每次输出堆顶元素,并将

剩余元素整理成新的最大堆再输出...

堆排序要解决的几个问题

1:如何将数据排列成堆的形式——初始堆的建立

2:输出堆顶元素后,剩余元素如何再整理成新的堆——堆的整理

3:输出元素放在什么位置

预备知识:

1: 堆中的元素存储在一个数组中,根据堆中的各元素之间具有

有序性关系,可以使用二叉树的方式来表示一个堆。因为各元素从前

至后存放在数组的钱n 个单元中,所以所画的二叉树实际上是一颗完全

二叉树

2: 所以根据完全二叉树的性质,数组前一半的数据都是分值节点,后一半

的数据都是叶子节点

3: 即如果有七个数,分别占据数组的a[1]-a[7],那么7/2=3,所以a[1],

a[2],a[3]为分支节点,剩下的为叶子节点

4: a[i]的左儿子为a[i*2],右儿子为a[i*2+1],如a[1]的左右儿子分别为

a[2]与a[3]。(这有赖于数组从a[0]开始,还是从a[1]开始)

建堆的过程:

见代码,见实例图

/*********************************************************/
/*数组从下标1开始*/

#include<iostream>
#define L(t) ((t)<<1)
#define R(t) ((t)<<1 | 1)
usingnamespace std;

intconst NUMBER = 1000;
int trees[NUMBER];
int N;
/*********************************************************/
void swap(int &a,int &b){
int temp = a;
a = b;
b = temp;
}
/*********************************************************/
//a[i]元素向下沉,此时堆中的实际元素为n,被甩在后面的元素
//已经不用管了
void ShiftDown(int i,int n){
int child;
//i<=n/2说明trees[i]为分支结点
//i=child;该句在循环最后执行,即从上往下递归判断
//新的位置是否已经稳定,不稳定继续下沉
for(;i<=n/2;i=child){
child = i*2;//先试着将预交换的元素设为左儿子
if((child != n) && trees[child+1]>trees[child])
child=child+1;//如果右儿子比左儿子大
//则将预交换儿子设置为右儿子
if(trees[child]>trees[i])//如果该节点不如较大的
//儿子大,则下沉(及交换)
swap(trees[child],trees[i]);
}
}
/*********************************************************/
void HeapSort(){
//该循环极为初始堆的建立,从最后一个分支结点开始
for(int i=N/2;i>=1;i--){
ShiftDown(i,N);
}
//每次循环首先使堆顶元素和首元素交换,再将首元素
//下沉到合适的位置,记得每次实际堆中元素减1
for(int i=N;i>=1;i--){
swap(trees[1],trees[i]);//最大的放到末尾
ShiftDown(1,i-1);      //所以此时的实际数量为i-1
}
}
/*********************************************************/
int main(){
while(cin>>N&&N!=0){
for(int i=1;i<=N;i++)
cin>>trees[i];
HeapSort();
for(int i=1;i<=N;i++)
cout<<trees[i]<<" ";
cout<<endl;
}
return0;
}

对一维数组进行堆排序

package com.test.sort;

public class TestHeapSort {

public static void main(String[] args) {
int[] array = {0,1,2,9,4,8,7,5};

heapSort(array);

for(int i=0; i<array.length; i++) {
System.out.print(array[i] + " ");
}

}

public static void heapSort(int[] array) {
for(int i=array.length/2; i>=1; i--) {   //创建二叉堆(从最后一个分支节点开始,依次向上)
shiftDown(array, i, array.length-1);
}

for(int i = array.length-1; i>=1; i--) {
swap(array, 1, i);				//将最大的元素与最后一个元素交换(解决最大元素放在哪里的问题)
shiftDown(array, 1, i-1);       //整理堆,从第一个结点开始,依次向下整理,到最后一个分支结点结束
}

}

public static void shiftDown(int[] array, int index, int length) {
int child = 0;
for(;index <= length/2; index = child) {
child = index * 2;
if(child<length && array[child]<array[child+1]) {
child = child+1;
}

if(array[index]<array[child]) {
swap(array,index,child);
}

}

}

public static void swap(int[] array, int index, int child) {
int x = array[index];
array[index] = array[child];
array[child] = x;
}

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