堆和优先队列
堆—尾部插入调整,从最后一层插入,自下向上调整,
堆–头部弹出调整,删除堆顶的元素,将堆尾的元素放到堆顶,维护完全二叉树,然后调整顺序
堆----优先队列
堆排序
- 将堆顶元素与堆尾元素交换
- 将此操作看作是堆顶元素的弹出操作
- 按照头部弹出以后的策略调整堆
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define swap(a,b){\
__typeof(a) __temp=a;\
a=b;b=__temp;\
}
typedef struct pri_queue{
int *data;
int cnt ,size;
}pri_queue;
//优先队列的初始化
pri_queue *init(int n){
pri_queue *q = (pri_queue *)malloc(sizeof(pri_queue));
q->data=(int *)malloc(sizeof(int)*(n+1));
q->cnt=0;
q->size=n;
return q;
}
//释放内存
void clear(pri_queue *q){
if(q==NULL)return ;
free(q->data);
free(q);
return ;
}
//判断是否为空
int empty(pri_queue *q){
return q->cnt==0;
}
int top(pri_queue *q){
return q->data[1];
}
//插入操作,自下向上判断,
int push(pri_queue *q,int val){
if(q==NULL) return 0;
if(q->cnt==q->size) return 0;
q->data[++(q->cnt)]=val;
//插入调整,
int ind=q->cnt;
//父节点不为零且当前值比父节点指大,交换
while(ind >>1&&q->data[ind]>q->data[ind>>1]){
swap(q->data[ind],q->data[ind>>1]);
ind>>=1;
}
return 1;
}
//弹出操作,自上向下判断,调整堆
int pop(pri_queue *q){
if(q==NULL) return 0;
if(empty(q)) return 0;
q->data[1]=q->data[q->cnt--];
int ind=1;
//左孩子变量合法
while((ind<<1)<=q->cnt){
int temp=ind,l=ind<<1,r=ind<<1|1;
if(q->data[l]>q->data[temp]) temp =l;
//右孩子结点要小于容量的值
if(r<=q->cnt&&q->data[r]>q->data[temp]) temp=r;
if(temp==ind) break;
swap(q->data[temp],q->data[ind]);
ind =temp;
}
return 1;
}
int main(){
srand(time(0));
#define max_op 20
pri_queue *q=init(max_op);
//循环创建max-op个元素,并且插入到优先队列
for(int i=0;i<max_op;i++){
int val=rand()%100;
push(q,val);
printf("insert %d to the pri_queue \n",val);
}
for(int i=0;i<max_op;i++){
printf("%d ",top(q));
pop(q);
}
printf("\n");
clear(q);
#undef max_op
return 0;
}
应用–堆排序
#include<iostream>
using namespace std;
void HeapAdjust(int *arr,int n,int i){
int smallest=i;
int l=2*i+1;
int r=2*i+2;
if(l<n&&arr[l]<arr[smallest])
smallest=l;
if(r<n&&arr[r]<arr[smallest])
smallest=r;
if(smallest!=i){
swap(arr[smallest],arr[i]);
i=smallest;
//递归调用
HeapAdjust(arr,n,i);
}
}
void HeapSort(int *arr,int n){
for(int i=n/2;i>=0;i--){
HeapAdjust(arr,n,i);
}
for(int i=n;i>=0;i--){
swap(arr[0],arr[i]);
HeapAdjust(arr,i-1,0);
}
}
int main(){
int arr[10]={12,4,5,2,1,12,8,9,11,10};
int len=sizeof(arr)/sizeof(int);
HeapSort(arr,len-1);
for(int i=0;i<len;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
return 0;
}
//根据数据结构优先队列改进而来
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
using namespace std;
void heapadjust(int *arr,int n,int ind){
while((ind<<1|1)<=n){
int temp=ind,l=ind<<1|1,r=2*ind+2;
if(arr[temp]<arr[l]) temp=l;
if(r<=n&&arr[temp]<arr[r]) temp=r;
if(temp==ind) break;
swap(arr[temp],arr[ind]);
ind = temp;
}
return;
}
void heapsort(int *arr,int n){
for(int i=n>>1;i>=0;i--){
heapadjust(arr,n,i);
}
for(int i=n;i>=0;i--){
swap(arr[i],arr[0]);
heapadjust(arr,i-1,0);
}
}
void output(int *arr,int n){
cout<<'[';
for(int i=0;i<n;i++){
cout<<arr[i]<<" ";
}
cout<<']'<<endl;
}
int main(){
srand(time(0));
#define max_n 20
int *arr=new int [max_n];
for(int i=0;i<max_n;i++){
arr[i]=rand()%100;
}
output(arr,max_n);
heapsort(arr,max_n);
output(arr,max_n);
delete[]arr;
return 0;
}