堆排序

来源:互联网 发布:java 类的实例 编辑:程序博客网 时间:2024/05/18 01:55
/*堆排序*/
# include <iostream>
using namespace std;
/*筛选算法:
  首先将完全二叉树的根节点中的记录移除,该记录成为待调整记录,此时根节点相当于空节点。
  从空节点的左右节点中选出一个值较大的记录,如果该记录的值大于待调整记录的值则将该记录移至空节点中
  此时那个值较大的记录(子节点)相当于空节点。重复上诉过程,直到空节点的左右子节点的值均都不大于待调整记录的值。
  此时将待调整记录放入空节点即可。
*/
void sift(int r[],int k,int m){
    /*假设r[k..m]是以r[k]为根的完全二叉树,且分别以r[2k]和r[2k+1]为根的左右子节点的大根堆,
    调整r[k],使整个序列满足堆的性质*/
    int t =  r[k];//暂存根记录r[k]
    int i = k;//根节点的位置
    int j = 2*i;//左子节点位置
    bool finish = false;
    while(j<=m&&!finish){
        if(j<m&&r[j]<r[j+1])j=j+1;
        if(t>=r[j])finish = true;
        else{
            r[i] = r[j];
            i = j;
            j = 2*i;
        }
    }
    r[i] = t;
}
void PrintArray(int r[]){
    for(int i=0;i<9;i++)
        cout<<r[i]<<"+ ";
    cout<<endl;
}
/*建立一个堆*/
void crt_heap(int r[],int length){
    int n = length;
    for(int i=n/2;i>=1;--i){//自第n/2个记录开始建堆。
       sift(r,i,n-1);
       PrintArray(r);
    }
}
/*堆排序:
对r[1..n]进行堆排序,执行本算法后,r中记录按值有小到大有序排序*/
void HeapSort(int r[],int length){
    crt_heap(r,length);
     int n = length;
     for(int i = n-1;i>=2;--i){
         int b = r[1];//将堆顶记录和堆中最后一个记录交换
         r[1] = r[i];
         r[i] = b;
         sift(r,1,i-1);//进行调整使r[1..r-1]变成堆
     }
}
void main(){
    int r[] = {0,48,62,35,77,55,14,35,98};
    PrintArray(r);
    //crt_heap(r,9);
    HeapSort(r,9);
    //sift(r,1,8);
    PrintArray(r);
}