堆排序----优化的选择排序

堆排序原理

        堆排序就是把最大堆(或最小堆)堆顶的元素取出,将剩余的堆继续调整为最大堆(最小堆),再次将最大堆(或最小堆)堆顶的元素取出,这一过程持续到剩余的堆只有一个元素时结束。

步骤        

        <1>产生最大堆:从下图我们可以看见,我们是至下而上地调整初始堆的,因为最大堆调整能够保证下标i的结点之后结点都满足最大堆的性质,所以至下而上的调整能够在改造过程中保持这一性质


<2>反复调整为最大堆,将堆顶元素和堆底元素交换,分离堆底元素,重复直到堆中剩下一个元素位置。


#include<stdio.h>

//最小堆实现的是降序

void FilterDown(int *ar, int start, int end)		//start,end都是物理下标
{
	int i = start;			//root
	int j = 2 * start + 1;	//leftchild
	int tmp = ar[i];
	while (j <= end)
	{
		if (j < end && ar[j] > ar[j+1])	j += 1;	//首先,判断右孩子是否存在;比较左右孩子,找出更小的那个

		if (tmp <= ar[j])	//找出放置start的位置
		{ 
			break;
		}
		
		ar[i] = ar[j];	//元素进行上移	
		i = j;
		j = 2 * i + 1;
	}

	ar[i] = tmp;
}

void Make_Heap(int *ar, int n) //调整为最小堆
{
	int end = n - 1;		//最后一个结点物理下标
	int pos = (end - 1) / 2;	//找到最后一个度为1的结点(分支结点)。

	while (pos >= 0)
	{
		FilterDown(ar, pos, end);	//由下至上依次调整
		--pos;
	}
}

void Swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Sort_Heap(int *ar, int n)	//n代表数组元素个数
{
	for (int i = 0; i < n-1 ; ++i)		//需要调整n-1次
	{
		int j = n - 1 - i;
		Make_Heap(ar, j+1);		//j是下标,j+1是当前堆中元素个数
		
		Swap(ar[0], ar[j]);	
	}
}

int main()
{
	int ar[] = { 45,78,12,34,90,56,8,18 };
	int n = sizeof(ar) / sizeof(ar[0]);
	Sort_Heap(ar, n);
	for (int i = 0; i < n; ++i)
		printf("%-4d", ar[i]);
        return 0;
}


本程序在VS2017下运行通过



猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/80633993
今日推荐