堆相关点,堆排序已测试通过代码
#include<stdio.h> const int maxn=1e5+5; int heap[maxn],n=10;//n是元素个数 void downAdjust(int low,int high)//向下调整,是要调整父亲,父亲的下标较小 { int i=low,j=i*2; while(j<=high) { if(j+1<=high && heap[j+1]>heap[j]) { j=j+1; } if(heap[j]>heap[i]) { int temp=heap[i]; heap[i]=heap[j]; heap[j]=temp; i=j;j=i*2; } else break; } } void createHeap(){ for(int i=n/2;i>=1;i--) downAdjust(i,n); } void deleteTop() { heap[1]=heap[n--]; downAdjust(1,n); } void upAdjust(int low,int high) { int i=high,j=i/2; while(j>=low) { if(heap[j]<heap[i]) { int temp=heap[i]; heap[i]=heap[j]; heap[j]=temp; i=j; j=i/2; } else break; } } void insert(int x) { heap[++n]=x; upAdjust(1,n); } void heapSort() { createHeap(); for(int i=n;i>=1;i--) { int temp=heap[i]; heap[i]=heap[1]; heap[1]=temp; downAdjust(1,i-1); } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&heap[i]); heapSort(); for(int i=1;i<=n;i++) printf("%d ",heap[i]); return 0; }
主要的几个函数
- downAdjust(int low,int high),是将父节点向下调整,low是父节点,high是最后一个可调整点。父节点需要跟两个节点中较大的一个比较
- upAdjust(int low,int high),是将子节点向上调整,子节点只需要和父节点比较。
- 前面两个函数都需要使用while,一次调整以后的新节点和其他的关系是未知的,如第一次就没动,终止,如果动,还需要向边界调整。
- 除了插入节点,是子节点的up,其他所有操作都是父节点的down(因为未知的三个点大小关系未知,up里面是另外一个点和父亲已知,只需要新节点和父亲比)
- 在新建堆的时候,从最后一个有孩子的父节点倒序向前面更新,这个三个点关系都未知的
- 在删除堆顶的时候,把最后一个顶上堆顶的位置,然后n-1,这时候新的父亲显然位置不对,需要更新。
- 在堆排序的过程钟,因为只知道堆顶是最大的,左右关系未知,所以每次堆以后就把堆顶和目前暂未排好序的最后一个元素替换,然后downAdjust新的堆顶。