堆排序与相关时间复杂度

Posted 两片空白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序与相关时间复杂度相关的知识,希望对你有一定的参考价值。

堆排序

要进行堆排序首先要数据建立成堆,想了解建立堆的小伙伴可以查看我的另外一博客建堆。只需要看向下调整推和建堆两个小部分即可。
下面来讲如何实现堆排序:

首先我们来讲一下堆排序的思路:
假设由N个元素。建立一个堆,然后将最后一个元素和第一个元素交换,这样就将最大值或者最小值放在了最后。
然后将前N-1个元素建立成堆,再用第一个元素与第N-1个元素交换,循环到只有一个元素。

在这里插入图片描述

代码(升序)

#include<stdio.h>
#include<windows.h>


void Swap(int *px, int *py){
	int temp = *px;
	*px = *py;
	*py = temp;

}
//大根堆
static void AdjustDown(HDdatatype a[], int size, int parent){
	int child = parent * 2 + 1;//先假设左边的数比根数大
	while (child < size){//没有孩子结点退出
		if (child + 1 < size&&a[child] > a[child + 1]){//如果右边的数大,child++就得到右边数的下标
			child++;
		}
		if (a[child] < a[parent]){//如果孩子结点比父节点大就就交换
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else{//直到不小就退出
			break;
		}
	}
}


void HeadBuild(int a[],int num){
	for (int i = ((num - 1 - 1) / 2); i >= 0; i--){
		AdjustDown(a, num, i);//建立堆
	}


}

void HeadSort(int a[],int num){
	for (int i = num - 1; i > 0; i--){
		Swap(&a[0], &a[i]);//交换
		AdjustDown(a, i, 0);//向下调整
	}
}


int main(){
	int a[] = { 27, 15, 18, 19, 35, 28, 65, 25, 49, 37 };
	int num = sizeof(a) / sizeof(a[0]);
	HeadBuild(a, num);//将一个数组建立成堆的形式
	HeadSort(a, num);//堆排序
	system("pause");
	return 0;
}

时间复杂度介绍

  1. 向下调整时间复杂度:

由于堆是一个完全二叉树,结点个数N有:N=2^H-1(不带括号,H是树高),就有H=log(N-1)。堆向下调整,最坏情况每一个都要调整,时间复杂度与高度有关所以时间复杂度是O(log(N))。

  1. 建堆的时间复杂度

建堆是从最后一个结点的父节点开始向下调整的,时间复杂度一般考虑最坏的情况,假设是满二叉树。所以有:
在这里插入图片描述

以上是关于堆排序与相关时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

堆排序(Java)

八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)

堆排序分析(JavaScript代码实现)

直接选择排序堆排序的联系与区别

JavaScript 数据结构与算法之美 - 归并排序快速排序希尔排序堆排序

算法与数据结构:堆排序