堆排序(1)HeapSort

heap_sort.h


#ifndef HEAP_SORT_H
#define HEAP_SORT_H
#include "utility.h"

typedef int ElemType;

class Sort
{
public:
	static void HeapSort(ElemType *arr,size_t n);

private:
	static void BuildMaxHeap(ElemType *arr,size_t n);  //数组应该有(n+1)个元素,第0个置空
	static void HeapAdjust(ElemType *arr,size_t i,size_t n);
	static void Swap(ElemType &e1,ElemType &e2);

	DISALLOW_COPY_AND_ASSIGN(Sort);
};

#endif

utility.h

/*----------------------------------------------- 
Created By EverSteins 
Email:EverSteins@gmail.com
转载请注明出处
------------------------------------------------*/ 

#ifndef UTILITY_H
#define UTILITY_H
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <stdlib.h>

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&)

#endif

heap_sort.cc


/*-----------------------------------------------  
Created By EverSteins  
Email:EverSteins@gmail.com 
转载请注明出处 
------------------------------------------------*/ 


#include "stdafx.h"
#include <iostream>
#include "utility.h"
#include "heap_sort.h"
using namespace std;

void Sort::HeapSort(ElemType *arr,size_t n)
{
	BuildMaxHeap(arr,n);

	for (size_t i=n;i>1;--i)    //注意i>1,循环(n-1)次。而不是循环(n-2)次
	{
		//key:将堆顶记录和当前未排序子序列的最后一个记录交换
		Swap(arr[1],arr[i]);    //注意下标是1
		HeapAdjust(arr,1,i-1);  //注意是i-1
	}
}

void Sort::BuildMaxHeap(ElemType *arr,size_t n)
{
	//构造一个大顶堆
	
	for (size_t i=n/2;i>0;--i)
		HeapAdjust(arr,i,n);
}


void Sort::HeapAdjust(ElemType *arr,size_t i,size_t n)
{
	//summmary:确保i结点的子树中(包括i结点)i结点是最大的
	//pre:1<=i<=n,数组arr应该有(n+1)个空间
	//已知[i,n]中的记录除i外均满足堆的定义
	//j总是为2*i或2*i+1
	ElemType tmp=arr[i];

	for (size_t j=2*i;j<=n;j*=2)
	{
		
		if (j<n && arr[j]<arr[j+1]) 
			++j;           //j为i左右子结点中较大的结点

		if (arr[j]<=tmp)   
			break;

		arr[i]=arr[j];  //将左右子结点中较大的结点赋值给父结点
		i=j; //i为变量是因为要始终成为j的父结点以赋值
	}

	//3种情况:1)传进来的参数i没有子结点 2)传进来的参数i是三结点(或两结点)中最大值 
	//3)(至少进入2次for循环)处于中间链,比左右子结点大 ;或处于底层结点
	arr[i]=tmp;
}

void Sort::Swap(ElemType &e1,ElemType &e2)
{
	ElemType tmp=e1;
	e1=e2;
	e2=tmp;
}

main.cc


/*-----------------------------------------------  
Created By EverSteins  
Email:EverSteins@gmail.com 
转载请注明出处 
------------------------------------------------*/ 

#include "stdafx.h"
#include <iostream>
#include "utility.h"
#include "heap_sort.h"
using namespace std;

typedef int ElemType;

void PrintArray(ElemType *arr,size_t n);

int _tmain(int argc, _TCHAR* argv[])
{
	//int arr[]={0,9,8,7,23,6,4,3,2,1,0};  //注意第一个元素没有意义,为哑元素。i从1开始
	int arr[]={0,8};
	size_t n=sizeof(arr)/sizeof(arr[0])-1;

	PrintArray(arr,n);
	Sort::HeapSort(arr,n);
	PrintArray(arr,n);

	system("pause");
	return 0;
}

void PrintArray(ElemType *arr,size_t n)
{
	for (size_t i=1;i<=n;++i)
		cout<<arr[i]<<' ';
	cout<<endl;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值