堆排序
堆排序的由来还得说到简单选择排序,由简单选择排序中的在进行剩余的n -2个数据比较时若能利用前n-1次比较的所得信息,则可以减少以后各趟排序的比较次数,由此联想出锦标赛排序也就是树形排序,但是树形排序的辅助存储空间较多,和“最大值”进行比较多余的比较等缺点,因此,在1964年威洛姆斯提出了堆排序,堆排序灵活的应用了最堆的特性来达到选择的目的。
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。
#include
int count = 0;
void swap(int k[], int i, int j)
{
int temp;
temp = k[i];
k[i] = k[j];
k[j] = temp;
}
void HeapAdjust(int k[], int s, int n)
{
int i, temp;
temp = k[s];
for( i=2*s; i <= n; i*=2 )
{
count++;
if( i < n && k[i] < k[i+1] )
{
i++;
}
if( temp >= k[i] )
{
break;
}
k[s] = k[i];
s = i;
}
k[s] = temp;
}
void HeapSort(int k[], int n)
{
int i;
for( i=n/2; i > 0; i-- )
{
HeapAdjust(k, i, n);
}
for( i=n; i > 1; i-- )
{
swap(k, 1, i);
HeapAdjust(k, 1, i-1);
}
}
int main()
{
int i, a[10] = {-1, 5, 2, 6, 0, 3, 9, 1, 7, 4};
HeapSort(a, 9);
printf("总共执行 %d 次比较!", count);
printf("排序后的结果是:");
for( i=1; i < 10; i++ )
{
printf("%d", a[i]);
}
printf("\n\n");
return 0;
}
#include
void swap(int arr[],int i,int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void heapify(int tree[],int n,int i) {
if(i >= n) {
return;//递归出口
}
int c1 = 2 * i + 1;//第一个子节点 ,左结点
int c2 = 2 * i + 2;//第二个子节点 ,右结点
int max = i;
if(c1 < n && tree[c1] > tree[max]) {
max = c1;
}
if(c2 < n && tree[c2] > tree[max]) {
max = c2;
}
if(max != i) {
swap(tree,max,i);
heapify(tree,n,max);
}
}
void build_heap(int tree[],int n) {
int last_node = n-1;
int parent = (last_node - 1) / 2;
int i;
for(i = parent;i >= 0;i--) {
heapify(tree,n,i);
}
}
void heap_sort(int tree[],int n) {
build_heap(tree,n);
int i;
for(i = n-1;i >= 0;i--) {
swap(tree,i,0);
heapify(tree,i,0);
}
}
int main() {
int tree[] = {-1, 5, 2, 6, 0, 3, 9, 1, 7, 4};
int n = 6;
heap_sort(tree,n);
int i;
for(i=0;i < n;i++) {
printf("%d\n",tree[i]);
}
return 0;
}