1. 程式人生 > 其它 >堆排序————資料結構課程

堆排序————資料結構課程

堆排序是個不穩定的演算法

堆排序的思路就是不斷維護一個大根堆(或者小根堆),然後不斷把堆頂元素拿出來(當然拿出來之後還需要維護),就可以得到一個有序序列。

1,根據所給序列建立一個大根堆。

2,從大根堆中拿出根元素(此時打破了堆的結構,需要對堆進行維護,即使得剩下的元素滿足堆的要求)。

3,不斷重複步驟2,直到所有的元素都已經被排序好。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;//堆排序
#define RecType int

void sift(RecType R[],int
low,int high) { //調整堆的演算法,逐級向下調整,直到編號為high的節點為止 int i=low, j=2*i; //R[j]是R[i]的左孩子 RecType tmp=R[i]; while (j<=high) { //這裡維護一個大根堆 if (j<high && R[j]<R[j+1]) j++; if (tmp<R[j]) { //雙親小 R[i]=R[j]; //將R[j]調整到雙親結點位置 i=j; //
修改i和j值,以便繼續向下篩選 j=2*i; } else break; //雙親大:不再調整 } R[i]=tmp; return; } void HeapSort(RecType R[],int n) { int i; RecType temp; for (i=n/2; i>=1; i--) //迴圈建立初始堆//因為n/2之後的節點肯定是葉子結點 sift(R,i,n); for (i=n; i>1; i--) { //進行n-1次迴圈,每次將堆頂的元素(最大值)放到佇列最後
temp=R[1]; //R[1] ? R[i] R[1]=R[i]; R[i]=temp; sift(R,1,i-1); //篩選R[1]結點,得到i-1個結點的堆 } } void disp(int R[],int n) { for(int i=1;i<=n;i++) printf("%d ",R[i]); printf("\n"); } int main() { RecType R[]={9,1,4,3,5,0,2,6,8,7}; int n=9; disp(R,n); HeapSort(R,n); disp(R,n); return 0; }
堆排序演算法