看这篇前请先把我上一篇了解一下:深入理解数据结构第一弹——二叉树(1)——堆-CSDN博客
前言:
目录
一、堆排序
1、堆排序的大体思路
在上一篇我们已经讲过了堆是什么东西,我们已经知道堆有大堆和小堆两种形式,堆排序的想法正是借助它的这个特点诞生的,例如:
2、堆排序的实例讲解
堆排序与堆相比并没有什么新东西,把我前面那章看明白,这里直接把代码呈上
(除了test.c)其他的是直接从上一章搬过来的
Seqlist.h
typedef int HPDataType;
typedef struct Heap
{
HPDataType* a;
int sz;
int capacity;
}HP;
//初始化
void HeapInit(HP* php);
//销毁
void HeapDestory(HP* php);
//插入
void HeapPush(HP* php, HPDataType x);
//删除
void HeapPop(HP* php);
//找堆顶元素
HPDataType HeapTop(HP* php);
//判断是否为空
bool HeapEmpty(HP* php);
//算个数
int HeapSize(HP* php);
test.c
//堆排序
void HeapSort(int* a, int n)
{
//建堆——向下调整建堆O(N-log(n))
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
int end = n - 1;
while (end > 0)
{
Swap(&a[0], &a[end]);
//再调整,选出次小数
AdjustDown(a, end, 0);
end--;
}
}
int main()
{
int a[] = { 7,8,3,5,1,9,5,4 };
HeapSort(a, sizeof(a) / sizeof(int));
return 0;
}
Seqlist.c
//堆
//初始化
void HeapInit(HP* php)
{
assert(php);
php->a = NULL;
php->capacity = 0;
php->sz = 0;
}
//销毁
void HeapDestory(HP* php)
{
free(php->a);
free(php);
}
//交换
void Swap(HPDataType* p1, HPDataType* p2)
{
HPDataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//删除
//向上调整(小堆)
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 AdjustDown(int* a, int n, int parent)
{
int child = parent * 2 + 1;
while (child<n)
{
if (child+1<n&&a[child + 1] < a[child])
{
++child;
}
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//插入
void HeapPush(HP* php, HPDataType x)
{
assert(php);
if (php->sz == php->capacity)
{
int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);
php->a = tmp;
php->capacity = newcapacity;
}
php->a[php->sz] = x;
php->sz++;
//向上调整
AdjustUp(php->a, php->sz - 1);
}
//删除
void HeapPop(HP* php)
{
assert(php);
assert(!HeapEmpty(php));
Swap(&php->a[0], &php->a[php->sz - 1]);
php->sz--;
//向下调整
AdjustDown(php->a, php->sz,0);
}
//判断是否为空
bool HeapEmpty(HP* php)
{
assert(php);
return php->sz == 0;
}
//找堆顶元素
HPDataType HeapTop(HP* php)
{
assert(php);
assert(!HeapEmpty(php));
return php->a[0];
}
//算个数
int HeapSize(HP* php)
{
assert(php);
return php->sz;
}
实现上述代码,我们就可以实现堆排序了
二、堆排序的时间复杂度
向下排序的时间复杂度
向上排序的时间复杂度
堆排序整体的时间复杂度
计算堆排序整体的时间复杂度就是计算上面这两步的时间复杂度
第一步:
第二步:
因此,堆排序的时间复杂度为O(N+N*log(N))
总结
堆排序及其时间复杂度的讲解就到此为止了,如果有不理解的地方欢迎在评论区中指出或者与我私信交流,欢迎各位大佬来访!!!
创作不易,还请各位大佬点赞支持!!!