堆排序 博客

http://hi.baidu.com/lxylxy888666/item/1bf1af17d69fb93db93180dc

 

 

 

不稳定算法--堆排序算法

 

堆排序算法是选择排序的一种,该算法只是通过堆,最大堆、或者最小堆选择出一个待排序序列中的最大值,或者最小值。


什么是堆:

n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):  (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子





排序过程:

不断的交换,得到堆顶最大元素9,堆顶与堆尾交换,除了9重新变成一个无序堆

重新生成堆

再把堆顶与倒数第二位交换,除了9,8剩下的又变成一个无序堆

重新生成堆

.....

生成一个完全有序堆




堆排序的C语言实现
#include <stdio.h>
#include <stdlib.h>
void HeapSort(int num[],int size);
void BuildHeap(int num[] ,int size);
void PercolateDown(int num[] , int index,int size);
void PrintHeap(const char* strMsg,int array[],int nLength); 
void Swap(int num[] , int v, int u);
int main(int argc, char *argv[])
{
  int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2};
  HeapSort(data,13);
  
  system("PAUSE");    
  return 0;
}
void HeapSort(int num[] ,int size)
{
    int i;
    int iLength=size;
    
    PrintHeap("Befor Sort:",num,iLength);
    
    BuildHeap(num,size);// 建立小顶堆   
    
    for (i = iLength - 1; i >= 1; i--) {   
        Swap(num, 0, i);// 交换   
        size--;// 每交换一次让规模减少一次   
        PercolateDown(num, 0,size);// 将新的首元素下滤操作 
        PrintHeap("Sort Heap:",num,iLength);  
    }
}
// 建堆方法,只需线性时间建好   
void BuildHeap(int num[] ,int size) { 
    int i; 
    for (i = size / 2 - 1; i >= 0; i--) {// 对前一半的节点(解释为“从最后一个非叶子节点开始,将每个父节点都调整为最小堆”更合理一些)   
        PercolateDown(num, i,size);// 进行下滤操作
        PrintHeap("Build heap:",num,size);
    }   
}
    
// 对该数进行下滤操作,直到该数比左右节点都小就停止下滤   
void PercolateDown(int num[] , int index,int size) {   
    int min;// 设置最小指向下标   
    while (index * 2 + 1<size) {// 如果该数有左节点,则假设左节点最小   
        min = index * 2 + 1;// 获取左节点的下标   
        if (index * 2 + 2<size) {// 如果该数还有右节点   
            if (num[min] > num[index * 2 + 2]) {// 就和左节点分出最小者   
                min = index * 2 + 2;// 此时右节点更小,则更新min的指向下标   
            }   
        }   
        // 此时进行该数和最小者进行比较,   
        if (num[index] < num[min]) {// 如果index最小,   
            break;// 停止下滤操作   
        } else {   
            Swap(num, index, min);// 交换两个数,让大数往下沉   
            index = min;// 更新index的指向   
        }   
    }// while   
}
    
// 给定数组交换两个数的位置   
void Swap(int num[] , int v, int u) {  
    int temp = num[v];   
    num[v] = num[u];   
    num[u] = temp;   
}   
void PrintHeap(const char* strMsg,int array[],int nLength)
{
     int i;
     printf("%s",strMsg);
     for(i=0;i<nLength;i++)
     {
        printf("%d ",array[i]);
     }
     printf("\n");
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值