最近在看算法导论,顺便把里面的程序都实现下,先拿堆排序来练练手吧。
首先介绍下堆调整,堆是一种数据结构,是一种完全二叉树(不一定是满二叉树),所以根节点与叶子节点满足关系如下:根节点下标为i,左叶子为下标2*i,右叶子下标为2*i+1,当然这里我们用数组来对堆进行存储。堆的子树必须满足如下关系,根节点大于左子树且大于右子树。
堆调整的方法如下,检测根节点是否为叶子节点,是退出,否调出子树中最大的值作为根节点,并对受影响的叶子节点进行递归调整。代码如下:
int modify(int length,int i,int array_sort[])
{
int max = i,r,l;
r = right(i);
l = left(i);
if(i > length/2) return 0;
if(l <= length && array_sort[l] > array_sort[max])
max = l;
if(r <= length && array_sort[r] > array_sort[max])
max = r;
if(max != i)
{
swap(array_sort[max],array_sort[i]);
modify(length,max,array_sort);
}
}
之后介绍建立堆,给定数组123456,得到堆,对得到的堆进行调整可以从第一个非叶子节点进行对调整,直到调整到根节点。代码如下:
void create_heap(int array_sort[],int length)
{
int i;
for(i = length/2;i >= 1; i--)
{
modify(length,i,array_sort);
}
}
最后介绍下堆排序的过程,首先对给定的数组建立堆,建立完成之后,堆顶必为最大的值,将堆顶与堆尾交换(即将堆定移除堆),之后重新对堆进行调整(堆长度减一),
之后再交换再调整,直到堆中只有一个数为止,全部代码如下:
#include<iostream>
#include<stdio.h>
#define left(x) (x)<<1
#define right(x) ((x)<<1)+1
#define LENGTH 10000
void swap(int &a,int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int modify(int length,int i,int array_sort[])
{
int max = i,r,l;
r = right(i);
l = left(i);
if(i > length/2) return 0;
if(l <= length && array_sort[l] > array_sort[max])
max = l;
if(r <= length && array_sort[r] > array_sort[max])
max = r;
if(max != i)
{
swap(array_sort[max],array_sort[i]);
modify(length,max,array_sort);
}
}
void create_heap(int array_sort[],int length)
{
int i;
for(i = length/2;i >= 1; i--)
{
modify(length,i,array_sort);
}
}
void heap_sort(int array_sort[],int length)
{
create_heap(array_sort,length);
for(int i = length;i >= 1; i--)
{
swap(array_sort[1],array_sort[i]);
modify(i-1,1,array_sort);
}
}
int main()
{
int length,i,array_sort[LENGTH];
printf("intput length of the array you want to sort\n");
scanf("%d",&length);
printf("int put the array now\n");
for(i = 1;i <= length; i++)
scanf("%d",&array_sort[i]);
heap_sort(array_sort,length);
for(i = 1;i <=length;i++)
printf("%d ",array_sort[i]);
system("pause");
return 0;
}