#include <iostream>
#include <algorithm>
using namespace std;
int n,op,x,len;
//构建大根堆
void min_heapify(int arr[],int start,int end){
int dad=start;
int son=dad*2+1;
while(son<=end){
if (son+1<=end && arr[son]>arr[son+1])
{
son++;
}
if (arr[dad]<arr[son])
{
return ;
} else {
swap(arr[dad],arr[son]);
dad=son;
son=dad*2+1;
}
}
}
//建堆
void make_heap(int arr[],int len){
//先对无序序列,构建堆。构建堆从下往上,从第一个非叶结点开始
for (int i = len/2-1; i >= 0; --i)
{
min_heapify(arr,i,len-1);
}
}
//进行堆排序
void heap_sort(int arr[],int len){
make_heap(arr,len);
// 堆排序的过程,根节点与最后一个叶子元素交换,再重新调整堆。如此循环往复
for (int i = len-1; i > 0; --i)
{
swap(arr[0],arr[i]);
min_heapify(arr,0,i-1);
}
}
void push(int arr[],int x){
//插入过程,先将元素放到末尾,然后上浮,与父节点比较,比父节点小就上浮
arr[len++]=x;
int now=len-1;
while(now){
// int dad=(now-1)/2;
int dad=now>>1;
cout << now << " " << dad << endl;
if (arr[now]<arr[dad])
{
swap(arr[now],arr[dad]);
now = dad;
} else {
break;
}
}
}
//删除操作
// 将堆顶元素与末尾元素交换,再调整堆
void pop(int arr[]){
swap(arr[0],arr[len-1]);
len--;
int now=0;
int son=now*2+1;//先是左
while(son<len){
if (son+1<len&&arr[son]>arr[son+1])
{
son++;
}
if (arr[now]>arr[son])
{
swap(arr[now],arr[son]);
} else {
break;
}
now=son;
son=son*2+1;
}
}
//本程序是小根堆相关操作
int main() {
int arr[]={3,4,3,9,7,8,6,5};
len = (int)sizeof(arr)/sizeof(int);
make_heap(arr,len);
cin>>n;
while(n){
n--;
cin>>op;//op 1:插入x 2:查询堆顶元素 3:删除堆顶元素 4:堆排序-逆序
switch(op){
case 1:
cin>>x;
push(arr,x);
break;
case 2:
cout<<arr[0]<<endl;
break;
case 3:
pop(arr);
case 4:
heap_sort(arr,len);
for (int i = 0; i < len; ++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
break;
}
}
return 0;
}
二叉堆相关操作及堆排序
最新推荐文章于 2024-10-20 23:59:56 发布