①定义
最大堆:对于任意二叉树节点,左右孩子节点的值都小于父亲节点的值。即根节点的值最大
最小堆:同理
②最大(小)堆的创建
接下来演示最小堆的创建,最大堆同理
堆的结构体如下:(由结构体可以看出,该树是由数组来进行保存树)
typedef struct Node *heap;
struct Node{
int* data; //用来存储数据的数组
int size; //当前堆含有几个元素
};
创建一个空的堆:
heap create_empty_heap(int n){
heap h = (heap)malloc(sizeof(struct Node));
h->data = (int *)malloc(sizeof(int) * (n+1));
h->size = 0;
h->data[0] = -9999; //创建最小堆的哨兵,进行上移的截止点,保证该data值一定最小
return h;
}
向最小堆中插入元素:
步骤:1.首先将size+1,并且直接将该元素直接插到最后一个节点,即完全二叉树
2.然后以此和父节点进行比较,若该节点比父节点小,则直接交换位置
void Insert(heap h,int x){
int i = ++h->size;
for (;h->data[i/2] > x; i = i/2){
h->data[i] = h->data[i/2];
}
h->data[i] = x;
}
获取当前最小堆中最小元素,即根节点元素,data[1]
操作步骤:1.返回值就是直接返回根节点元素
2.然后将最后一个节点元素,即data[h->size] 默认放到根节点
3.然后维护该最小堆,从根节点Parent = 1,向下找两个儿子child节点中最小的节点
4.将该根节点值与两个儿子结点的值进行比较,如比两个儿子节点的值都大,则完成最小堆排序
否则,将该根节点与儿子节点交换位置,在循环该儿子节点为根节点进行排序最小堆
int delete_minheap(heap h){
int x = h->data[h->size--];
int ans = h->data[1];
int child,parent;
for (parent = 1; parent * 2 <= h->size; parent = child){
child = parent * 2;
if (child + 1 <= h->size && h->data[child+ 1] < h->data[parent])
child++;
if(h->data[child] > x)
break;
h->data[parent] = h->data[child];
}
h->data[parent] = x;
return ans;
}
③堆排序
堆排序的时间复杂度为nlogn ,因为遍历n个节点,每次获取最小值的时间复杂度为Logn(原因是每次获取最小值后,重构最小堆的时间复杂度为Logn,即为树的深度)
下面为堆排序的演示代码:
#include<time.h>
#include<stdio.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<set>
#include<stack>
using namespace std;
typedef struct Node *heap;
struct Node{
int* data;
int size;
};
heap create_empty_heap(int n){
heap h = (heap)malloc(sizeof(struct Node));
h->data = (int *)malloc(sizeof(int) * (n+1));
h->size = 0;
h->data[0] = -9999; //创建最小堆的哨兵,进行上移的截止点,保证该data值一定最小
return h;
}
void Insert(heap h,int x){
int i = ++h->size;
for(;h->data[i/2] > x; i = i/2){
h->data[i] = h->data[i/2];
}
h->data[i] = x;}int delete_minheap(heap h){
int x = h->data[h->size--];
int ans = h->data[1];
int child,parent;
for (parent = 1; parent * 2 <= h->size; parent = child){
child = parent * 2;
if (child + 1 <= h->size && h->data[child+ 1] < h->data[parent])
child++;
if(h->data[child] > x)
break;
h->data[parent] = h->data[child];
}
h->data[parent] = x;
return ans;
}
int main(){
int n,data;
heap h;
cin >> n;
h = create_empty_heap(n);
for (int i = 1; i<=n; i++){
cin>>data;
Insert(h, data);
}
for (int i = 1; i<=n; i++){
cout << delete_minheap(h) << " ";
}
return 0;
}