堆排序————数据结构课程

 堆排序是个不稳定的算法

堆排序的思路就是不断维护一个大根堆(或者小根堆),然后不断把堆顶元素拿出来(当然拿出来之后还需要维护),就可以得到一个有序序列。

 

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;
}
堆排序算法

 

posted @ 2021-12-22 14:34  浪矢-CL  阅读(33)  评论(0编辑  收藏  举报