您的位置:首页 > 其它

堆排序

2014-11-18 16:54 176 查看
堆排序

a[] = {4,1,3,2,16,9,10,14,8,7};

现在对数组A组建一个(二叉树)堆。

a[0] = 4,

a[1] = 1,

a[2] = 3,

a[3] = 2,

a[4] = 16,

a[5] = 9,

a[6] = 10,

a[7] = 14,

a[8] = 8,

a[9] = 7;

依据数组的下标,因为 (0+1) *2 = (1+1), (0+1)*2 +1 = (2+1)

可将a[0]视为a[1]和a[2]的根;

a[1]视为a[3]和a[4]的根。

依次类推,为方便观察可将数组如下从下标1开始。

a[1] = 4,

a[2] = 1,

a[3] = 3,

a[4] = 2,

a[5] = 16,

a[6] = 9,

a[7] = 10,

a[8] = 14,

a[9] = 8,

a[10] = 7;

其关系为

#define PARENT(i) (i)>>1

#define LEFT(i) (i)<<1

#define RIGHT(i) ((i)<<1)+1

从最底层的树叶开始将数组建成最大堆排列:16,14,10,8,7,9,3,2,4,1.

这样每个结点的树根都是这个子树中的最大的值而且堆的树根是整个数组的最大值。

建立好最大堆之后树根和最底层的树叶交换,之后重新建立n-i个结点的最大堆。一直到最后一个结点。

/************************************************************************/
//堆排序过程
//			1.将数组组建成最大堆。(堆顶为最大值)
//			2.分两部分:
//				(1)将最大值与堆底的元素交换(将最大值放到数组的最后)
//				(2)对除去最后一个最大值的堆调整成新的最大堆。
/************************************************************************/
void HeapSort(int* a, int n)
{
int i;
int heapSize = n;
BuildMaxHeap(a,n);
Debug(a,n,0);

for(i=n-1; i>0; i--)
{
Swap(&a[0],&a[i]);
heapSize--;
MaxHeapify(a,heapSize,1);
}
}
/************************************************************************/
//建立最大堆
//从最后一个结点开始,依次调整每个结点,使之成为最大堆
/************************************************************************/
void BuildMaxHeap(int* a,int n)
{
int i;
for(i=n/2; i>0;i--)
{
MaxHeapify(a,n,i);
}
}
/************************************************************************/
//使以i为根的子堆成为最大堆
/************************************************************************/
void MaxHeapify(int* a,int n,int i)
{
int l = LEFT(i);
int r = RIGHT(i);
int largest;
Debug(a,n,0);
if(l<=n && a[i-1]<a[l-1])
{
largest = l;
}
else
{
largest = i;
}
if(r<= n && a[r-1] > a[largest-1])
{
largest = r;
}
if(i != largest)
{
Swap(&a[i-1],&a[largest-1]);
MaxHeapify(a,n,largest);
}

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