文章目录
创建最大堆类
class Maxheap
{
private:
//存放元素的堆数组
int* heap;
//数组的空间长度
int arrayLength;
//数组中元素的个数
int heapSize;
//扩容数组的函数
void changeLength(int*& old, int oldLength, int newLength)
{
if (oldLength <= newLength)
{
cout << "newlength should > oldlength" << endl;
return;
}
//创建新数组
int* temp = new int[newLength];
//复制
for (int index = 1; index < oldLength; index++)
{
temp[index] = old[index];
}
delete[] old;
old = temp;
}
public:
Maxheap(int capacity = 10)
{
//数组从1开始
heap = new int[capacity + 1];
arrayLength = capacity + 1;
heapSize = 0;
}
//插入元素
void push(int element)
{
if (heapSize == arrayLength - 1)
{
int newLength = arrayLength * 2;
changeLength(heap, arrayLength, newLength);
}
//获取要添加的节点位置的索引
//并将元素个数+1
int currentNode = ++heapSize;
//当不是根节点且根节点元素小于插入的元素
while (currentNode != 1 && element > heap[currentNode / 2])
{
//将根节点元素下移
heap[currentNode] = heap[currentNode / 2];
//将元素索引上移
currentNode = currentNode / 2;
}
heap[currentNode] = element;
}
//返回优先级最高的元素
int top()
{
if (heapSize == 0)
{
cout << "the heap is empty" << endl;
//这里正常应该是抛出异常,这里省略了
return -111111111;
}
return heap[1];
}
//删除最大的元素
void pop()
{
if (heapSize == 0)
{
cout << "the heap is empty" << endl;
return;
}
int lastElement = heap[heapSize--];
int currentNode = 1;
int child = 2;
while (child <= heapSize)
{
//找heap[currentNode]的更大的孩子
if (child < heapSize && heap[child] < heap[child + 1])
{
child++;
}
if (lastElement > heap[child])
{
break;
}
heap[currentNode] = heap[child];
currentNode = child;
child *= 2;
}
heap[currentNode] = lastElement;
}
//将一个数组初始化为最大堆
void initialize(int* array, int size)
{
delete[] heap;
//先生成完全二叉树
heap = array;
heapSize = size;
//找到最后一个具有孩子的节点
for (int root = heapSize / 2; root >= 1; root--)
{
int rootEle = heap[root];
int child = root * 2;
while (child <= heapSize)
{
//找孩子中较大的那一个
if (child < heapSize && heap[child] < heap[child + 1])
{
child++;
}
//如果根元素大于最大的孩子,就直接结束循环
if (rootEle >= heap[child])
{
break;
}
//如果根元素比最大的孩子小,就将孩子上移
heap[child / 2] = heap[child];
//移到下一层,直到为根元素找到合适的位置
child *= 2;
}
//将原本的根元素放到合适的位置上去
heap[child / 2] = rootEle;
}
}
friend ostream& operator<<(ostream& cout, Maxheap& m);
};
ostream& operator<<(ostream& cout, Maxheap& m)
{
for (int index = 1; index <= m.heapSize; index++)
{
cout << m.heap[index] << " ";
}
return cout;
}
堆排序方法
void heapSort(int a[], int size)
{
Maxheap m;
m.initialize(a, size);
for (int i = size - 1; i >= 1; i--)
{
int x = m.top();
m.pop();
//讲弹出的元素放在数组的最后面,不再新开辟数组
a[i + 1] = x;
}
}
完整代码,使用随机数生成要排序的数
随机数范围为0-max(用户手动输入)
#include<iostream>
#include<ctime>
using namespace std;
//最大堆类
class Maxheap
{
private:
//存放元素的堆数组
int* heap;
//数组的空间长度
int arrayLength;
//数组中元素的个数
int heapSize;
void changeLength(int*& old, int oldLength, int newLength)
{
if (oldLength <= newLength)
{
cout << "newlength should > oldlength" << endl;
return;
}
//创建新数组
int* temp = new int[newLength];
//复制
for (int index = 1; index < oldLength; index++)
{
temp[index] = old[index];
}
delete[] old;
old = temp;
}
public:
Maxheap(int capacity = 10)
{
//数组从1开始
heap = new int[capacity + 1];
arrayLength = capacity + 1;
heapSize = 0;
}
//插入元素
void push(int element)
{
if (heapSize == arrayLength - 1)
{
int newLength = arrayLength * 2;
changeLength(heap, arrayLength, newLength);
}
//获取要添加的节点位置的索引
//并将元素个数+1
int currentNode = ++heapSize;
//当不是根节点且根节点元素小于插入的元素
while (currentNode != 1 && element > heap[currentNode / 2])
{
//将根节点元素下移
heap[currentNode] = heap[currentNode / 2];
//将元素索引上移
currentNode = currentNode / 2;
}
heap[currentNode] = element;
}
//返回优先级最高的元素
int top()
{
if (heapSize == 0)
{
cout << "the heap is empty" << endl;
return -111111111;
}
return heap[1];
}
//删除最大的元素
void pop()
{
if (heapSize == 0)
{
cout << "the heap is empty" << endl;
return;
}
int lastElement = heap[heapSize--];
int currentNode = 1;
int child = 2;
while (child <= heapSize)
{
//找heap[currentNode]的更大的孩子
if (child < heapSize && heap[child] < heap[child + 1])
{
child++;
}
if (lastElement > heap[child])
{
break;
}
heap[currentNode] = heap[child];
currentNode = child;
child *= 2;
}
heap[currentNode] = lastElement;
}
//将一个数组初始化为最大堆
void initialize(int* array, int size)
{
delete[] heap;
//先生成完全二叉树
heap = array;
heapSize = size;
//找到最后一个具有孩子的节点
for (int root = heapSize / 2; root >= 1; root--)
{
int rootEle = heap[root];
int child = root * 2;
while (child <= heapSize)
{
//找孩子中较大的那一个
if (child < heapSize && heap[child] < heap[child + 1])
{
child++;
}
//如果根元素大于最大的孩子,就直接结束循环
if (rootEle >= heap[child])
{
break;
}
//如果根元素比最大的孩子小,就将孩子上移
heap[child / 2] = heap[child];
//移到下一层,直到为根元素找到合适的位置
child *= 2;
}
//将原本的根元素放到合适的位置上去
heap[child / 2] = rootEle;
}
}
friend ostream& operator<<(ostream& cout, Maxheap& m);
};
ostream& operator<<(ostream& cout, Maxheap& m)
{
for (int index = 1; index <= m.heapSize; index++)
{
cout << m.heap[index] << " ";
}
return cout;
}
//对数组a进行堆排序
void heapSort(int a[], int size)
{
Maxheap m;
m.initialize(a, size);
for (int i = size - 1; i >= 1; i--)
{
int x = m.top();
m.pop();
a[i + 1] = x;
}
}
int main()
{
//用户手动输入要排序数据的总数
int n = 0;
cout << "请输入要排序的数的个数" << endl;
cin >> n;
//用户输入数的范围
cout << "请输入参与排序的数的最大值" << endl;
int max = 0;
cin >> max;
//随机数种子
srand((unsigned)time(NULL));
int* a = new int[n + 1];
//指定a[0]的值为0,从索引1-n排序
a[0] = 0;
//使用随机数初始化要进行排序的数组
for (int index = 1; index <= n; index++)
{
a[index] = rand() % (max + 1);
}
//进行堆排序
heapSort(a, n);
//输出结果
for (int index = 1; index <= n; index++)
{
cout << a[index] << " ";
}
}