参考博客:http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621
堆排序:
即给定一个数组,
第一阶段是先初始化堆:
步骤是:1. 从倒数第一个非叶子节点开始,与它的左右孩子比较,若小于任何一个,即把它们交换;(注意,交换后,若不是倒数第一个非叶子节点,一旦交换,有可能引起新的堆顶元素小于它的左或者右孩子,需要再交换(递归处理)
2. 依次从倒数第二个非叶子节点开始......
第二个阶段:排序:
步骤是:1. 把顶元素R[1]与倒数第一个元素R[n]进行交换,然后这时堆原有秩序有可能打破(R[1....n-1]需要重新检查排序,用初始化的方式)
2. 吧顶元素R[1]与倒数第二个元素R[n-1]进行交换,........
3. 依次类推。。。
注意这使得堆是先序的形式完全二叉树
void main()
{
int[] list = new int[] { 3, 9, 8, 5, 7, 7, 12, 1 };
int len=list.Length;
HeapSort heap = new HeapSort();
heap.InitHeap(list, len);
for(int i = 0;i<len;i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine("");
heap.SortHeap(list, len);
for (int i = 0; i < len; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine("");
}
public class HeapSort
{
//初始化堆的流程:1. 从最后一个非叶子节点开始判断(判断改节点与他的左右节点比较,是不是最大的;若不是最大的,就交换这两个节点, 注意交换之后,若它的孩子节点的不符合大顶堆,也要通过递归再做调整)
// 2. 依次类推去判断倒数第二个非叶子节点.....
public void InitHeap(int[] list, int len)
{
if(list==null||len<=0) return;
for (int i = len / 2 - 1; i >= 0; i--)
{
AdjustHeap(list, i, len);
}
}
private void swap(int[] list, int index1, int index2)
{
int temp = list[index1];
list[index1] = list[index2];
list[index2] = temp;
}
//判断改节点与他的左右节点比较,是不是最大的;若不是最大的,就交换这两个节点, 注意交换之后,若它的孩子节点的不符合大顶堆,也要通过递归再做调整
public void AdjustHeap(int[] list, int currentIndex, int len)
{
if (list == null || currentIndex < 0 || len <= 0) return;
int lChildIndex = 2 * (currentIndex + 1) - 1;
int rChidIndex = 2 * (currentIndex + 1);
if (currentIndex <= len / 2 - 1)
{
int maxIndex = currentIndex;
if (lChildIndex<len && list[maxIndex] < list[lChildIndex])
{
maxIndex = lChildIndex;
}
if (rChidIndex<len && list[maxIndex] < list[rChidIndex])
{
maxIndex = rChidIndex;
}
if (maxIndex != currentIndex)
{
swap(list, maxIndex, currentIndex);
AdjustHeap(list, maxIndex, len);
}
}
}
//堆排序:1. 就是拿堆顶元素R[1]与倒数第一个叶子节点R[n]进行交换,交换后,看R[1...R-1]是否仍是大顶堆,若不是,需要调整(注意这里有递归)
// 2. 依次拿堆定元素R[1]余倒数第二个叶子节点R[n-1]进行交换,交换后,看R[1...n-2]是否仍是大顶堆........
// 3. 依次到最后一个元素
public void SortHeap(int[] list, int len)
{
for(int i=len-1; i>=0; i--)
{
swap(list, 0, i);
AdjustHeap(list, 0, i - 1);
}
}
}