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

重温堆排序

时间:2016-05-29 21:31:06      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

郑重声明:本文99.99%转载自http://blog.csdn.net/morewindows/article/details/6709644/

快一年没碰堆排序了……在这里给自己 总结 搞晕一下。

*堆排序基于二叉堆

  • 二叉堆的定义

    二叉堆是完全二叉树或者是近似完全二叉树。

    二叉堆满足二个特性:

    1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

    2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

  • 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:技术分享
  • 由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。
  • 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。上图:技术分享
  • 堆的插入、删除

  • 堆的插入:

 

 1 //  新加入i结点  其父结点为(i - 1) / 2  
 2 void MinHeapFixup(int a[], int i)  
 3 {  
 4     int j, temp;  
 5       
 6     temp = a[i];  
 7     j = (i - 1) / 2;      //父结点  
 8     while (j >= 0 && i != 0)  
 9     {  
10         if (a[j] <= temp)  
11             break;  
12           
13         a[i] = a[j];     //把较大的子结点往下移动,替换它的子结点  
14         i = j;  
15         j = (i - 1) / 2;  
16     }  
17     a[i] = temp;  
18 }  
  • 堆的删除:

    代码和以上类似,就不赘述了。但是要注意:堆的插入是从下至上,堆的删除是从上至下!堆的删除要寻找子节点中最小或最大的节点,与其替换,重复这个步骤直至自己在子节点中最小。这样,堆才是可维护的。

 

以上是对堆的基础知识与操作。下面是堆排序的流程

  • 堆化数组(堆排序第一步)

  堆化数组只有一个方法——对堆中的元素进行向下调整(类似于堆的删除,只不过把根节点换成了普通节点)。而且调整的顺序是从下至上!!!

  这就相当于把更大(或更小)的数据换了上来,一直换到堆的最上方。而那些次要的数据就被留在下面。

实现代码:

1 //建立最小堆  
2 void MakeMinHeap(int a[], int n)  
3 {  
4     for (int i = n / 2 - 1; i >= 0; i--)  
5         MinHeapFixdown(a, i, n);  
6 }  
  • 堆交换(堆排序第二步)

  每次提取堆的根节点,然后对堆进行一次删除操作。这样可把次大的节点换上来……

1 void MinheapsortTodescendarray(int a[], int n)  
2 {  
3     for (int i = n - 1; i >= 1; i--)  
4     {  
5         Swap(a[i], a[0]);  
6         MinHeapFixdown(a, 0, i);  
7     }  
8 }  

這樣就夶功告成叻

(当然还要输出啦^(* ̄(oo) ̄)^)


╭︿︿︿╮
{/ o o /}  
 ( (oo) )   
 ︶ ︶︶    {The king of the pig}

 

重温堆排序

标签:

原文地址:http://www.cnblogs.com/MyNameIsPc/p/5540323.html

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