堆,逻辑上是一个完全二叉树,实现是一个数组。时间复杂度O(N*logN)。二叉树的高度就决定了O(logn)这个结论。
堆两个操作:1.heapInsert() 加一个新值到堆里 ,值与父比,如果大则交换位置。
2.heapify() 减一个最大的值
前面有篇是JAVA版,本篇为C++版。实例亲测有效,供大家参考。
//arr[0...index-1]已经是堆 index是新加数的下标
//index 数与父比较,>父,与父交换
void heapInsert(int arr[], int index)
{
while (arr[index] > arr[(index - 1) / 2])// 加入的值>父值 交换 子 i 父 (i-1)/2
{
swap(arr, index, (index - 1) / 2);//父子交换值
index = (index - 1) / 2; //下标更改
}
}
//删最大值
//1.堆最后一个数放头
//2.有效区个数-1
//3.头向下调整 当前为父 与两子比较
void heapify(int arr[], int index, int size)
{
int left = index * 2 + 1;
while (left < size) //左孩子不越界 下方还有孩子
{
//左右孩子谁大 谁给largest
int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
//右孩子 不越界 右>左
largest = arr[largest] > arr[index] ? largest : index;
//父亲和孩子谁大,把下标给largest
if (largest == index)
{
break;
}
swap(arr, largest, index);
index = largest; //来到下方
left = index * 2 + 1;//找右孩子
}
}
void heapSort(int arr[], int m_num)
{
cout << "heapSort******************" << endl;
if (arr == NULL || m_num < 2) { return; }
方法1:一个一个的插入数据
for (int i = 0; i < m_num; i++)
{
heapInsert(arr, i);
}
//方法2:一次输入一组数据
/*/
for (int i = m_num-1; i >= 0; i--)
{
heapify(arr, i, m_num);
}*/
int heapSize = m_num;
//头尾交换
swap(arr, 0, --heapSize);
while (heapSize > 0)
{
heapify(arr, 0, heapSize);//父子 子子 比较
swap(arr, 0, --heapSize);
}
for (int i = 0; i < m_num; i++)
{
cout << arr[i] << endl;
}
}