码迷,mamicode.com
首页 > 编程语言 > 详细

15. 蛤蟆的数据结构进阶十五排序实现之堆排序

时间:2015-08-17 23:42:25      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

15. 蛤蟆的数据结构进阶十五排序实现之堆排序

         本篇名言:“谁要是游戏人生 ,他就一事无成 ; 谁不能主宰自己 ,永远是一个奴隶--歌德”

         继续来看下堆排序。

欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47733553

1.  堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

(a)大顶堆序列:(96,83,27,38,11,09)

  (b)  小顶堆序列:(12,36,24,85,47,30,53,91)

 

如图建堆初始过程:无序序列:(49,38,65,97,76,13,27,49)
                                       

 技术分享

 

 

2.  代码实现

从一个无序序列建堆的过程就是一个反复筛选的过程。若将此序列看成是一个完全二叉树,则最后一个非终端节点是第[n/2]个元素,由此筛选只需从第[n/2]个元素开始。

代码核心是先将数组假想为完全二叉树。那么偶数位的数是左孩子,奇数位的数是右孩子。

先将数组进行完全二叉树处理,然后将根节点提取出来放到数组最后,将原先数组的最后一个元素放到根节点,因为不能保证原先数组最后一个的元素是剩下元素中最大的,所以要紧接着做一次处理(此次处理将最后一个元素除外)。接下去是继续去根节点放到数组倒数第二个位置,以此循环。

实现如下图1

技术分享

3.  源码

#include"stdio.h"

 

void print(inta[],intn){ 

         for(intj= 0; j<n; j++){ 

                   printf("%d",a[j]); 

         } 

 

 

 

/**

*已知H[s…m]除了H[s]外均满足堆的定义

*调整H[s],使其成为大顶堆即将对第s个结点为根的子树筛选

*

* @param H是待调整的堆数组

* @param s是待调整的数组元素的位置

* @param length是数组的长度

*

*/ 

void HeapAdjust(intH[],ints, int length

         inttmp  = H[s]; 

         intchild = 2*s+1; //左孩子结点的位置。(i+1为当前调整结点的右孩子结点的位置

         while(child < length) { 

                   if(child+1<length && H[child]<H[child+1]){ // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点

                            ++child; 

                   } 

                   if(H[s]<H[child]){ // 如果较大的子结点大于父结点 

                            H[s]= H[child]; // 那么把较大的子结点往上移动,替换它的父结点 

                            s =child;       // 重新设置s ,即待调整的下一个结点的位置 

                            child= 2*s+1; 

                   }  else {            // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出 

                            break

                   } 

                   H[s]= tmp;         // 当前待调整的结点放到比其大的孩子结点位置上 

         } 

//       print(H,length); 

 

 

/**

*初始堆进行调整

*H[length-1]建成堆

*调整完之后第一个元素是序列的最小的元素

*/ 

void BuildingHeap(intH[],intlength

{  

         //最后一个有孩子的节点的位置 i=  (length -1) / 2 

         for (int i= (length -1) / 2 ; i >= 0; --i) 

                   HeapAdjust(H,i,length); 

/**

*堆排序算法

*/ 

void HeapSort(intH[],intlength

         //初始堆 

         BuildingHeap(H,length); 

         //从最后一个元素开始对序列进行调整 

         for (int i= length - 1; i > 0; --i) 

         { 

                   //交换堆顶元素H[0]和堆中最后一个元素 

                   inttemp = H[i]; H[i]= H[0]; H[0]= temp; 

                   //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整 

                   HeapAdjust(H,0,i); 

         } 

}  

 

int main(){ 

         intH[10] = {3,1,5,7,2,4,9,6,10,8}; 

         printf("初始值:\n"); 

         print(H,10); 

         HeapSort(H,10); 

         //selectSort(a,8); 

         printf("\n堆排序后值:\n"); 

         print(H,10); 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

15. 蛤蟆的数据结构进阶十五排序实现之堆排序

标签:

原文地址:http://blog.csdn.net/notbaron/article/details/47733553

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!