最小堆【总结附简易代码】
这里主要贴一些简易代码。
依次插入结点建堆
插入在最后,所以每次是向上过滤
void Build_Min_Heap(int a[],int n) { int i,j; for(i=1;i<=n;i++) { scanf("%d",&a[i]); j=i; while(j>1&&a[j]<a[j/2]) { swap(a[j],a[j/2]); j>>=1; } } }
对整体建堆
//以这个根节点向下过滤。 void Adjust(int a[],int i,int n) { int Child,temp; for(temp=a[i];(2*i)<=n;i=Child) { Child=2*i; //左儿子结点 if(Child+1<=n&&a[Child]>a[Child+1]) Child++; //取个更小的。 if(a[Child]<temp) a[i]=a[Child]; else break; } a[i]=temp; //将temp放到当前位置。 } //已经把结点存入后,依次枚举带子节点的结点,然后向下过滤 void Build_Min_Heap(int a[],int n) { for(int i=n/2;i>=1;i--) Adjust(a,i,n); }
堆删除根节点后的调整
void Adjust(int a[],int i,int n) { int temp,Child; for(temp=a[i];2*i<=n;i=Child) { Child=2*i; if((2*i+1)<=n&&a[Child]>a[Child+1]) Child++; if(a[Child]<temp) a[i]=a[Child]; else break; } a[i]=temp; } // 堆删除 根节点 后的调整(保证一定能删除) void Delete(int a[],int n) { a[1]=a[n]; n--; Adjust(a,1,n); }
堆排序
//从小到大排序
//先建最大堆(所以很明显这里整体建堆很方便啊,但是我们完全可以利用那个过滤的函数也很方便)
//然后依次取首位元素,向下过滤
void Adjust(int a[],int i,int n) { int temp,Child; for(temp=a[i];2*i<=n;i=Child) { Child=2*i; if(Child+1<=n&&a[Child]<a[Child+1]) Child++; if(a[Child]>temp) a[i]=a[Child]; else break; } a[i]=temp; } void HeapSort(int a[],int n) { for(int i=n/2;i>=1;i--) Adjust(a,i,n); for(int i=n;i>=2;i--) { swap(a[1],a[i]); Adjust(a,1,i-1); } }