堆排序分为大根堆和小根堆。
堆排思想:(采用树的概念来组织数据结构,在这里我是根据小根堆对数据进行排序)
①首先我们Insertheap一组数据,在插入的过程中采用向上调整(Shiftup),每次将插入的最小值放在堆顶(heap[0]).
②然后我们Removeheap创建好的堆,将heap[0]节点剔除作为返回值,每次都将最后一个叶子节点赋值到heap[0],然后在执行向下调整(ShiftDown),查找到根节点以下最小的节点,重新创建小跟堆。
#include<iostream>
#include<assert.h>
using namespace std;
#define DEFAULT_SIZE 10
//堆排
class BigHeap
{
public:
BigHeap(int sz = DEFAULT_SIZE)
{
capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;
heap = new int[capacity];
cursize = 0;
}
~BigHeap()
{
delete[]heap;
heap = NULL;
capacity = cursize = 0;
}
public:
void Insert(int& x)
{
if (cursize >= capacity)
return;
heap[cursize] = x;
ShiftUp(cursize);
cursize++;
}
int RemoveHeap()
{
assert(cursize != 0);
int key = heap[0];
heap[0] = heap[cursize - 1];
cursize--;
ShiftDown(0);
return key;
}
public:
void ShiftUp(int pos)
{
int i = (pos - 1) / 2;
int j = pos;
int tmp = heap[j];
while (j > 0)
{
if (tmp < heap[i])
{
heap[j] = heap[i];
j = i;
i = (j - 1) / 2;
}
else
break;
}
heap[j] = tmp;
}
void ShiftDown(int pos)
{
int i = pos;
int j = i * 2 + 1; //父的左子树节点
int tmp = heap[i];
while (j < cursize)
{
if (j + 1 < cursize && heap[j] > heap[j + 1])
j++;
if (heap[j] < tmp)
{
heap[i] = heap[j];
i = j;
j = i * 2 + 1;
}
else
break;
}
heap[i] = tmp;
}
private:
int* heap;
int cursize;
int capacity;
};
void HeapSort(int* a, int n)
{
BigHeap small(n);
for (int i = 0; i < n; i++)
small.Insert(a[i]);
for (int i = 0; i < n; i++)
{
a[i] = small.RemoveHeap();
}
}
int main()
{
int arr[] = { 23,12,11,2,5,16,26,37,59,29 };
int n = sizeof(arr) / sizeof(int);
HeapSort(arr, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}