堆排序

 今天准备把之前遇到过的经典算法都自己根据理解写一遍。这是一个很好的提高编程技巧的过程。

这次写的算法是堆排序,虽然我知道我这个算法在对于网上众多堆排序算法简直就像XXXX的裹脚布一样XXXX....但是些算法这种东西我一直觉得都是可以精简精简再精简,慢慢改改就会好,但是我还是不想发优化后的堆排序算法,因为那样就会忽略掉自己编程中的一些思路问题与一些犯的错误。

这次贴的代码乱七八糟的,希望能给有些同学带来一些思路的同时给大家一些提醒....

现在来谈谈我对堆排序的简单粗暴的理解吧:

泛泛的谈就是一个递归的过程。

个人觉得堆排序还是一个很不错的算法,体现了很多编程的思想,大家如果能都自己不看别人的事例代码自己敲一遍那是极好...我去看别人写的事例代码了,看看比我写得好在哪...下面,上代码...(这次用的是VC++6.0的编译器,个人感觉比VS2010真TMD难用很多,而且还有一些BUG,不过没办法,听说很多地方机试都是用这个编译器)

//堆排序
/*
调用方式:HeadSort(a,MAXSIZE,cmp_2);最后一个参数如果是cmp_1为非递减排列,cmp_2为非递增排列
*/
#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
//调整堆(大堆  1为<  2为>)
void HeadAdjust(int a[],int i,int size,const int (*cmp)(const int,const int))
{//i为逻辑编号,1开始算起,cmp为比较函数
	int *lchild = NULL;//左孩子
	int *rchild = NULL;//右孩子
	int temp;
	if(2*i > size)//i节点为叶子节点
		return ;
	//	do
	//	{
	if(2*i < size)//i为有左,右孩子的非叶子节点
	{
		
		lchild = &a[2*i-1];
		rchild = &a[2*i];
		int *best = cmp(*lchild,*rchild) ? rchild : lchild;//改2
		if(cmp(a[i-1],*best))//改1
		{
			temp = a[i-1];
			a[i-1] = *best;
			*best = temp;
		}
		
		i = best-a + 1;	
	}
	if(2*i == size)//i为只有左孩子的飞叶子节点
	{
		lchild = &a[2*i-1];
		if(cmp(a[i-1],*lchild))//改1
		{
			temp = a[i-1];
			a[i-1] = *lchild;
			*lchild = temp;
		}
		return ;
		//	break;
	}
	HeadAdjust(a,i,size,cmp);
	//	}while(cmp(a[i],a[2*i-1]) || cmp(a[i],a[2*i]));//改1
}

void BuildHead(int a[],int size,const int (*cmp)(const int,const int))
{
	for(int i = size;i > 0;--i)
	{
		HeadAdjust(a,i,size,cmp);
	}
}
void HeadSort(int a[],int size,const int (*cmp)(const int,const int))
{
	int temp;
	BuildHead(a,size,cmp);
	for(int i = size;i > 0;--i)
	{
		temp = a[i-1];
		a[i-1] = a[0];
		a[0] = temp;
		HeadAdjust(a,1,i-1,cmp);
	}
}

//非递减
const int cmp_1(const int a,const int b)
{
	return a<=b;
}
//非得增
const int cmp_2(const int a,const int b)
{
	return a>=b;
}

#define MAXSIZE 100

int main(int argc, char* argv[])
{
	
	int a[MAXSIZE]={0};
	srand(time(0));
	for(int i = 0;i < MAXSIZE;++i)
	{
		a[i] = rand()%MAXSIZE;
	}
	
	//	int a[] = {0,0,3,4,1,2,7,9,9,9};
	HeadSort(a,MAXSIZE,cmp_2);
	printf("Hello World!\n");
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值