快速学习“堆“排序(C语言数据结构)

前言:

        堆的实现其实并不难,难的是要用堆实现排序,也就是堆的运用

        下面需要探究一下堆的排序是怎样的。

        如何利用堆进行升序或者降序的排序。

"堆排序":

   原理:

        例如:此时要将数组里的数组int arr[] = {12,20,26,8,1,2,3}进行升序或者降序排序

第一步:把数放进堆里面,但是究竟是放在大堆还是小堆里面呢?

如果需要升序就需要放进大堆里面!

如果需要降序就需要放进小堆里面!

(原因后续画图讲解)

如何将一个数组直接放在大堆当中呢?

可以直接遍历数组,将数一个一个放入。

代码如下:

typedef int HPDataType;
void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(hp->_a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("malloc::error");
			exit(-1);
		}
		hp->_capacity = newcapacity;
		hp->_a = tmp;
	}
	hp->_a[hp->_size] = x;
	hp->_size++;
	AdjustUp(hp->_a, hp->_size - 1);
}
void test2()
{
	Heap hp;
	HeapInit(&hp);
	int arr[] = {12,20,26,8,1,2,3};
	int i = 0;
	int size = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < size; i++)
	{
		HeapPush(&hp, arr[i]);
	}

}

此时就直接形成了”大堆“。

第二步:每次需要交换首和尾

              交换之后将除了新的尾的数之外的数进行向下调整

              也就是将除了26以外的数进行向下调整:

向下调整:

第三步:以此类推,直到遍历到第一个数为止。

大家可以亲自动手画一画,很有助于理解。

我把这个方法称之为“沉淀法”!

此时最后就是一个升序的树,可以直接按照顺序打印出来。

代码如下:

void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(hp->_a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("malloc::error");
			exit(-1);
		}
		hp->_capacity = newcapacity;
		hp->_a = tmp;
	}
	hp->_a[hp->_size] = x;
	hp->_size++;
	AdjustUp(hp->_a, hp->_size - 1);
}
void HeapInit(Heap* hp)
{
	assert(hp);
	hp->_a = NULL;
	hp->_capacity = hp->_size = 0;
}
void AdjustDown(HPDataType* a, int size, int parent)
{
	//假设最大的孩子的值是左孩子对应的数值
	int childmax = (parent * 2) + 1;
	while (childmax < size)
	{
		//如果右有孩子并且右孩子的值是大于左孩子将最大的孩子换成右孩子
		if (childmax + 1 < size && a[childmax + 1] > a[childmax])
		{
			childmax = childmax + 1;
		}
		if (a[parent] < a[childmax])
		{
			swap(&a[parent], &a[childmax]);
			parent = childmax;
			childmax = (parent * 2) + 1;
		}
		else
		{
			break;
		}
	}
}
void test2()
{
	Heap hp;
	HeapInit(&hp);
	int arr[] = {12,20,26,8,1,2,3};
	int i = 0;
	int size = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < size; i++)
	{
		HeapPush(&hp, arr[i]);
	}
	for (i = 0; i < size; i++)
	{
		//交换首尾
		swap(&hp._a[0], &hp._a[hp._size - 1 - i]);
		//向下调整
		AdjustDown(hp._a, hp._size-1-i, 0);
	}
	for (i = 0; i < size; i++)
	{
		arr[i] = hp._a[i];
	}
	for (i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	//test1();
	test2();
	return 0;
}

"十万个数据"进行堆排序:

        大数据时代,如果有10万个数据要进行排序,该怎么排序。

        究竟是用哪种排序的方式时间复杂度最低呢?

     在这之前需要我们计算一下”堆排序“的时间复杂度!

建堆的时间复杂度:


堆排序的时间复杂度:

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值