排序-----堆排序

原理:给定N个数,把这些数看成是一棵顺序存储的完整二叉树,然后将其调整为一个大顶堆(小顶堆),然后将堆的最后一个元素和堆顶元素交换,此时堆的最后一个元素就是最大(最小)的数;接着将前(N-1)个元素重新调整为一个大顶堆(小顶堆),再将堆顶元素和当前堆的最后一个元素交换得到次最大元素,重复该过程直到最后调整的堆只剩下一个元素为止,此时可得一个有序序列。

//堆排序
#include<stdio.h>
//交换两数
void Swap(int *a, int *b)
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
//建堆,保证父结点不大于子子节点
void AdjustMinHeap(int a[], int pos, int len)
{
	int temp, child;
//父结点为temp = a[pos]
	for (temp = a[pos];pos * 2 + 1 <= len;pos = child)
	{
//子节点为child = pos*2+1
		child = pos * 2 + 1;
//求出最小的子节点对应的下标
		if (child<len && a[child]>a[child + 1])
			++child;
//当父结点大于其最小的子节点的时候,交换两者
		if (a[child] < temp)
			a[pos] = a[child];
		else
			break;
	}
	a[pos] = temp;
}

void MyMinHeapSort(int array[], int len)
{
	int i;
//找到第一个非叶子点建堆,len/2-1即为第一个非叶子的结点,并从此结点开始依次比较父结点和子节点的大小
	for (i = len / 2 - 1;i >= 0;--i)
		AdjustMinHeap(array, i, len - 1);
//依次交换堆的第一个元素和从第n个到第2个的位置,交换一次建堆一次
	for (i = len - 1;i >= 0;--i)
	{
		Swap(&array[0], &array[i]);
		AdjustMinHeap(array, 0, i - 1);
	}
}

int main()
{
	int array[] = { 1,4,7,9,2,3,5,8 };
	int len = sizeof(array) / sizeof(array[0]);
	MyMinHeapSort(array,len);
	for (int i = 0;i < len;++i)
		printf("%d ", array[i]);
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39916039/article/details/81668739