您的位置:首页 > 其它

heapsort

2012-12-05 17:28 363 查看
/*
* szlHeapSort.h
*/
#ifndef SZL_HEAP_SORT_H
#define SZL_HEAP_SORT_H

void heapSort(int a[], int n);
void siftDown(int a[], int root, int n);

#endif


/*
* szlSwap.h
*/
#ifndef SZL_SWAP_H
#define SZL_SWAP_H

//交换两个数
void swap(int *a, int *b);

#endif

/* szlHeapSort.c
* 堆是其节点值满足一定约束的完全二叉树;
* 数组实现的n个节点的完全二叉树满足的性质,如果
* 1.用A[0..n-1]表示这棵树,那么
* (1)位置i的父节点为(i-1)/2;
* (2)位置i的孩子节点为2*i+1及2*i+2;
* (3)第一个叶子节点是n/2;
* 2.用A[1..n]表示这棵树,那么
* (1)位置i的父节点为i/2;
* (2)位置i的孩子节点为2*i及2*i+1;
* (3)第一个叶子节点是n/2+1;
*/
#include "szlHeapSort.h"
#include "szlSwap.h"
#include "stdio.h"

/*
* 将具有n个元素的数组a进行堆排序
*/
void heapSort(int a[], int n){
int i;
/*
* 以数组a为输入,建立一个堆
*/
for(i=(n/2)-1; i>=0; i--){ // 从最后一个内部节点降序地访问到树根节点
siftDown(a,i,n); // 将每一个节点下沉,建立以位置i为根节点的子堆,sub heap
}

/*
* 将树根节点和最后一个叶子节点交换;
* 并将堆的大小减少1;
* 然后调整树根,以保持堆序;
* 循环,直至访问到第2个元素
*/
for(i=n-1; i>=1; i--){
swap(&a[0],&a[i]);
siftDown(a,0,i);
}
}

/*
* 将root位置的节点在大小为n的堆a中调整,以保持堆序
*/
void siftDown(int a[], int root, int n){
int done, maxChild;

done = 0;
while(!done){

if(root*2+2<=n-1){ //如果root存在左孩子和右孩子
if(a[root*2+1]>a[root*2+2]){ //max记住较大的孩子
maxChild=root*2+1;
}
else{
maxChild=root*2+2;
}
}
else if(root*2+1==n-1){ // 如果root有左孩子
maxChild=root*2+1;
}
else{ //没有孩子节点
maxChild = root; // 标记root为最大的元素
}

if(a[root] < a[maxChild] ){ // 将最大的元素和root位置的元素交换
swap(&a[maxChild],&a[root]);
root=maxChild; //以较大的孩子为根节点继续往下访问
}
else{
done=1;
}
}
}


 

/*
* szlSwap.c
*/
#include "szlSwap.h"

void swap(int *a, int *b){
int t=*a;
*a=*b;
*b=t;
}


 更为简洁的版本:

/*
* heapsort.c
*/
#include <stdio.h>
#define N 30

void swap (int * p, int * q){
if (! (p == q)){
* p ^= * q;
* q ^= * p;
* p ^= * q;
}
}

void sift_down (int a[], int i, int n){
int max = i;
if ( 2*i+2 <= n-1){
max = a[2*i+1] > a[2*i+2] ? (2*i+1) : (2*i+2);
}
else if (2*i+1 == n-1){
max = 2*i+1;
}
if (a[max] > a[i]){
swap (&a[i], &a[max]);
sift_down (a, max, n); /* recursion */
}
}

void build_heap (int a[], int n){
int i;
for (i=(n-1)/2; i>=0; i--){
sift_down (a, i, n);
}
}

void heapsort (int a[], int n){
int i;
build_heap (a, n);
for (i=n-1; i>0; i--){
swap (&a[0], &a[i]);
sift_down (a, 0, i);
}
}

int main (int argc, char ** argv){
int n;
int i;
int a
;
#ifdef DEBUG1
freopen ("in.txt", "r", stdin);
#endif
scanf ("%d", &n);
for (i=0; i<n; i++)
scanf ("%d", &a[i]);

heapsort (a, n);

for (i=0; i<n; i++)
printf ("%d ", a[i]);

#ifdef DEBUG1
fclose (stdin);
#endif
return 0;
}


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