算法思路:
将数组逻辑结构理解为二叉树,然后利用大根堆特性,将二叉树调整为大根堆后,根节点即为最大的数,然后将最大的数与二叉树最后一个数交换位置,则最后一位排好位置。然后将堆的大小减一,对交换后的二叉树进行变换,使之成为大根堆,然后根节点的数即为第二大的数,将它换到现在二叉树的末尾位置,然后堆大小减一。依此类推可将所有数据排序。
存储结构:
代码
可理解为二叉树中的冒泡法。
参考左神代码编写
#include <iostream>
using namespace std;
void swap(int arr[], int index1, int index2)
{
int temp;
temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
void show(int a[], int len)
{
cout << "The sort is:" << endl;
for (int i = 0; i < len; i++)
{
cout << a[i] << " ";
}
}
void heapInsert(int arr[], int index) // Generate a large root heap up
{
while (arr[index] > arr[(index - 1) / 2])
{
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
void heapify(int arr[], int index, int heapsize) // Generate a large root heap down
{
int left = 2 * index + 1;
while (left < heapsize)
{
int largest = left + 1 < heapsize && arr[left + 1] > arr[left] ? left + 1 : left; // find the largest number of child nodes
largest = arr[largest] < arr[index] ? index : largest; // compare the current number with the child node
if (largest == index)
{
break;
}
swap(arr, index, largest);
index = largest;
left = 2 * index + 1;
}
}
void heapsort(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
heapInsert(arr, i);
}
int heapsize = len;
swap(arr, 0, --heapsize);
while (heapsize > 1)
{
heapify(arr, 0, heapsize);
swap(arr, 0, --heapsize);
}
}
void duipai()
{
int arr[] = {2, 5, 9, 7, 1, 8, 6, 4, 3, 20};
int len = sizeof(arr) / sizeof(arr[0]);
heapsort(arr, len);
show(arr, len);
}
int main()
{
duipai();
return 0;
}
TIPS:
堆的性质:
1.是一个完全二叉树
2.每个节点的值大于(小于)子节点的值,为大(小)根堆
堆中数据用数组存放,下标为 i 的结点的父结点下标为(i-1)/2;其左右子结点分别为 (2i + 1)、(2i + 2)
堆中比较重要的两个操作是:heapinsert 和heapify。用于将二叉树调整为大根堆。