让算法会说话之堆排序

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/26364047

       堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

一.堆的删除

虽然在这里我默认读者对“堆”是有所了解的,但是这里我仍然要讲一下堆的删除,因为这直接影响你对下面堆排序的理解。

这里以删除最小元为例讲解,当然下面的堆排序时删除最大元,但这并不妨碍我们对“堆的删除”的理解。

核心思想:将最小元删掉,其他的元根据堆的性质排好。

二.堆排序算法

/***************************************************************
*版权所有 (C)2014,公司名称。
*
*文件名称:堆排序法
*内容摘要:无
*其它说明:无
*当前版本:V1.0
*作   者:若云流风
*完成日期:2014.5.20
***************************************************************/
#include <stdio.h>

#define N  7
#define LeftChild(i)   (2*(i)+1)              //i节点的左儿子节点

void disp(void);

int a[N]={5,0,7,1,9,11,12};

/*下滤函数(目的:根据堆的性质将堆排好)*/
void PerDown( int a[], int i ,int M)
{
	int Child,tmp;

	for( tmp=a[i]; LeftChild(i)<M; i=Child )       //将根节点赋值tmp,判断根的左儿子是否存在
	{
		Child=LeftChild(i);
		if( Child !=M-1  &&  a[Child+1]>a[Child] ) //判断节点儿子是否是两个(M为奇数时),如果是两个再判断哪个更大
			Child++;
		if( tmp<a[Child] )                         //将节点的儿子与节点比较,如果儿子大则交换位置
			a[i]=a[Child];
		else
			break;                                 //否则退出循环
	}
	a[i] =tmp;                                     //如果节点的儿子大实际执行的是a[Child]=a[i];否则a[i]的值没有变化
}

/*排序函数*/
void HeapSort(void)
{
	int i,temp;

	for(i=N/2;i>=0;i--)  /*BuildHeap*/
		PerDown(a,i,N);
	disp();              //调试打印1  (将无序数组变成堆后的数组)

	for(i=N-1;i>0;i--)   /*DeleteMax*/
	{
		temp = a[0];     /*删掉最大元:将他移到数组末尾*/
		a[0] = a[i];
        a[i] = temp;
		disp();          //调试打印2  (将最大元素放到末尾的数组)
		PerDown(a,0,i);  /*每次下滤上次最大的元(现在在数组末)都不再参与*/
		disp();          //调试打印3  (下滤后的新数组)

	}
	disp();              //调试打印4  (最终的数组)
}  

/*输出函数*/
void disp(void)
{
     int i;

     printf("\n排序结果: \n");
	 for(i=0;i<N;i++)
	 {
		printf("%d", a[i]);
		printf("  ");
	 }

}

int main(void)
{
	HeapSort();
    //disp();
	return 0;

}

三.算法会说话

1.结果输出

2.结果分析

好吧我承认也许只看上图也许有些晕,不要紧,接着看我分析。

首先看看如何将数组变成堆:

最终结果就是结果输出中的的“1”。

然后再来看看整个排序的过程:

参考:1.数据结构与算法分析---C语言描述     Mark Allen Weiss 著

让算法会说话之堆排序

时间: 2024-07-30 20:52:08

让算法会说话之堆排序的相关文章

十大基础实用算法之快速排序和堆排序

快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来. 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists). 算法步骤: 1 从数列中挑出一个元素,称为 "基准"(pi

让算法会说话之归并排序

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/27570953 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作.归并排序算法依赖归并操作. 一.归并排序算法 /*************************************************************** *版权所有 (C)2014,公司名称. * *文件名称:归并排序法 *内容摘要:无 *其它说明:无 *

让算法会说话之快速排序

        转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/30729523        快速排序是由东尼.霍尔所发展的一种排序算法.在平均状况下,排序n 个项目要O(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来. 一.排序步骤总结: 快速排序使

#排序算法#【3】堆排序

堆是一个完全二叉树,树中每个结点对应于原始数据的一个记录,并且每个结点应满足以下条件:非叶结点的数据大于或等于其左.右孩子结点的数据(若是按从大到小的顺序排序,则要求非叶结点的数据小于或等于其左.右孩子结点的数据). 由堆的定义可看出,其根结点为最大值,堆排序就是利用这一特点进行的.堆排序过程包括两个阶段: (1)将无序的数据构成堆(即用无序数据生成满足堆定义的完全二叉树). (2)利用堆排序(即用上一步生成的堆输出有序的数据). 加入有一组要排序的数据:69,65,90,37,92,6,28,

让算法会说话之冒泡排序

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25972987 冒泡排序:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 一.冒泡排序算法以及优化 1.常用代码 /**************************************

让算法会说话之希尔排序

这是我参照之前在iOS项目中用过的一个不规则形状按钮的第三方Button,这里用Cocos2d-x实现一个相似功能的按钮. 原文地址:http://blog.csdn.net/qqmcy/article/details/26161339 代码下载:http://download.csdn.net/detail/qqmcy/7365843 使用方法: .h // // TestScene.h // maptest // // Created by 杜甲 on 14-5-18. // // #ifn

让算法会说话之插入排序

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/26059615 插入排序:它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 一.插入排序算法 /*************************************************************** *版权所有 (C)2014,公司名称. * *文件名称:插入排序法 *内容摘要:无 *其它说明:无 *当前版

算法导论——lec 06 堆排序

堆数据结构是一种数组对象,它可以被视为一颗完全二叉树,树中每个节点和数组中存放该节点值的那个元 素对应.如果表示堆的数组为A,那么树的根为A[1]. 一. 堆 1. 表示堆的数组A是一个具有两个属性的对象:length(A)是数组中的元素个数,heap-size(A)是存放在A中的堆的 元素个数:A[heap-size(A)]之后的元素都不属于相应的堆.也就是:Heap-size(A)<=length(A). 2. 给定某个节点的下标i,其父节点PARENT(i),左儿子LEFT(i)和右儿子R

算法有插入排序,堆排序,合并排序,快速排序和stooge排序

比较的算法有插入排序,堆排序,合并排序,快速排序和stooge排序, 先说一下比较结果 1,比较插入和stooge排序,stooge的表现如此之差,数组大小在2000时 InsertSort VS StoogeSort 's Running Time:     16ms:47672ms; Terribly! Isn't It? 所以在后面的比较中,没有带stooge这个垃圾算法 2,插入排序,堆排序,合并排序,快速排序运行时间对比 (网易博客的表格功能太差了,不爽,只好以文本对齐展现给大家了):