#include<iostream> #include<algorithm> #include<cassert> using namespace std; //大顶堆 根节点为1,左孩子为2i 右孩子为2i+1 //对于每一个孩子的父亲为i/2 class MaxHeap { private: int* data; int count; int capacity; void shiftUp(int k) { while( k>1 && data[k/2]<data[k])//控制边界,当k=1时就不需要再比了 { swap( data[k/2], data[k]); k/=2; } } void shiftDown(int k) { while(2*k <=count) { int j=2*k;//此轮循环中,data[j]和data[k]交换 if(j+1<=count &&data[j+1]>data[j])//如果有右孩子且比左孩子大 { j+=1; } if(data[k]>=data[j]) break; swap(data[k],data[j]); k=j; } } public: MaxHeap(int capacity) { data=new int[capacity+1]; count=0; this->capacity= capacity; } MaxHeap(int arr[],int n)//heapify 将一个数组中的元素构造成堆 //不需要再一个一个的插入操作 { data=new int[n+1]; capacity=n; for(int i=0;i<n;i++) { data[i+1]=arr[i]; } count=n; for(int i=count/2;i>=1;i--)//从第一个不是叶子结点开始 { shiftDown(i); } } ~MaxHeap() { delete []data; } int size() { return count; } bool isEmpty() { return count==0; } void insert(int item) { assert(count+1 <= capacity); data[count+1]=item; count++; shiftUp( count ); } int extractMax() { assert(count>0); int ret=data[1]; swap(data[1],data[count]); count--; shiftDown(1); return ret; } }; void heapSort1(int arr[],int n) { MaxHeap maxheap=MaxHeap(n); for(int i=0;i<n;i++)//逐个插入的算法复杂度是nlogn { maxheap.insert(arr[i]); } for(int i=n-1;i>=0;i--) { arr[i]=maxheap.extractMax(); } } void heapSort2(int arr[],int n) { MaxHeap maxheap=MaxHeap(arr,n);//heapify的算法复杂度是n for(int i=n-1;i>=0;i--) { arr[i]=maxheap.extractMax(); } } //heapify 最后一个除以2得到的序号就是第一个不是叶子结点的序号 void __shiftDown(int arr[],int n,int k) { //现在是从0开始了, 左孩子为2*k+1 while(2*k+1 < n) { int j=2*k+1;//此轮循环中,data[j]和data[k]交换 if(j+1<n && arr[j+1]>arr[j])//如果有右孩子且比左孩子大 { j+=1; } if(arr[k]>=arr[j]) break; swap(arr[k],arr[j]); k=j; } } //原地堆排序 void heapSort(int arr[],int n)//在原数组上进行排序 不需要另外再开一个空间 { for(int i=(n-1)/2;i>=0;i--)//heapify 先进行一次heapify 当然现在数组是以0为下标开始的 { __shiftDown(arr,n,i); } for(int i=n-1;i>0;i--) //然后将最大的换到后面 然后此时前n-1个又不满足大顶堆,再从开始处shiftdown { swap(arr[0],arr[i]); __shiftDown(arr,i,0); } } int main() { MaxHeap maxheap=MaxHeap(100); int arr[100]; for(int i=0;i<100;i++) { arr[i]=100-i; } for(int i=0;i<100;i++) { cout<<arr[i]<<" "; } cout<<endl; cout<<"-----------"<<endl; /* while(!maxheap.isEmpty()) { cout<<maxheap.extractMax()<<" "; }*/ heapSort1(arr,100); for(int i=0;i<100;i++) { cout<<arr[i]<<" "; } cout<<endl; cout<<"-----------"<<endl; heapSort2(arr,100);//效率还是快的 for(int i=0;i<100;i++) { cout<<arr[i]<<" "; } cout<<endl; cout<<"-----------"<<endl; heapSort(arr,100);//效率还是快的 for(int i=0;i<100;i++) { cout<<arr[i]<<" "; } return 0; }