堆:
大顶堆:根结点比左右子树更大;小顶堆:根节点比左右子树更小。
- 定义一个堆:
const int main=100; //heap为堆,n为元素个数 int heap[maxn],n=10;
- 调整堆:
//在heap数组在[low,high]范围进行向下调整 //其中low为欲调整的结点的数组下标,high一般为堆的最后一个元素的数组下标 void downAdjust(int low,int high){ int i=low,j=2*i; //i为欲调整结点,j为其左孩子 while(j<=high){ //存在孩子结点 //如果右孩子存在,且右孩子的值大于左孩子 if(j+1<=high&&heap[j+1]>heap[j]){ j=j+1; //让j存储右孩子下标 } //如果孩子中最大的权值比欲调整结点i大 if(heap[j]>heap[i]){ swap(heap[j],heap[i]); //交换最大权值的孩子与欲调整结点i i=j; //保持i为欲调整结点、j为i的左孩子 j=2*i; }else{ break; //孩子的权值比欲调整结点i要小,调整结束 } } }
- 建立堆:
void createHeap(){ for(int i=n/2;i>=1;i--){ downAdjust(i,n); } }
- 删除堆顶元素:
void deleteTop(){ heap[1]=heap[n--]; //用最后一个元素覆盖堆顶元素,并让元素个数减1 downAdjust(1,n); //向下调整堆顶元素 }
- 在堆内添加元素:
//添加元素向上操作 //对heap数组在[low,high]范围进行向上调整 //其中,对low一般设置为1,high表示欲调整结点的数组下标 void upAdjust(int low,int high){ int i=high,j=i/2; //i为欲调整结点,j为其父亲 while(j>=low){ //父亲权值小于欲调整i的权值 if(heap[j]>heap[i]){ swap(heap[j],heap[i]); i=j; j=i/2; }else{ break; } } } //添加元素x void insert(int x){ heap[++n]=x; //让元素个数加1,然后经数组末尾赋值为x upAdjust(1,n); //向上调整新加入的结点n }
- 堆排序:
void heapSort(){ createHeap(); //建堆 for(int i=n;i>1;i--){ swap(heap[i],heap[1]); downAdjust(1,i-1); } }