Heap.h
#define _CRT_SECURE_NO_WARNINGS
#pragma once
typedef int HPDataType;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct Heap {
HPDataType* _a;
HPDataType _size;
HPDataType _capacity;
}Heap;
void AdjustDown(HPDataType* a, int n, int root);
void HeapInit(Heap* php, HPDataType*a,int n);
void HeapDestory(Heap* php);
void HeapPush(Heap* php,HPDataType x);
void HeapPoP(Heap* php);
HPDataType HeapTop(Heap* php);
Heap.c
#define _CRT_SECURE_NO_WARNINGS
#include "Heap.h"
void Swap(HPDataType* a, HPDataType* b)
{
HPDataType temp = *a;
*a = *b;
*b = temp;
}
//前提,左右子树都是小堆的情况下,
//向下调整法
void AdjustDown(HPDataType*a,int n,int root)
{
int parent = root;
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 = 2 * child + 1;
}
else
{
break;
}
}
}
void AdjustUp(HPDataType*a,int n, int child)
{
int parent = (child - 1) / 2;
while (parent>0)
{
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void HeapInit(Heap* php, HPDataType* a, int n)
{
php->_a = (HPDataType*)malloc(sizeof(HPDataType) * n);
//检测是否开辟成功
memcpy(php->_a, a, sizeof(HPDataType) * n);
php->_size = n;
php->_capacity = n;
//构建堆
for (int i = (n - 1 - 1) / 2; i >= 0; --i)
{
AdjustDown(php->_a, php->_size, i);
}
}
void HeapDestory(Heap* php)
{
assert(php);
free(php->_a);
php->_size = NULL;
php->_capacity = NULL;
}
void HeapPush(Heap* php, HPDataType x)
{
assert(php);
if (php->_size == php->_capacity)
{
php->_capacity *= 2;
HPDataType* tmp = (HPDataType*)realloc(php->_a, sizeof(HPDataType) * php->_capacity);
php->_a = tmp;
}
php->_a[php->_size++] = x;
AdjustUp(php->_a, php->_size, php->_size - 1);
}
void HeapPoP(Heap* php)
{
assert(php);
assert(php->_size > 0);
Swap(&php->_a[0], &php->_a[php->_size - 1]);
php->_size--;
AdjustDown(php->_a, php->_size, 0);
}
HPDataType HeapTop(Heap* php);
Test.c
#define _CRT_SECURE_NO_WARNINGS
#include "Heap.h"
void HeapSort(HPDataType* a, int 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[] = { 27,15,19,18,28,34,65,49,25,37 };
HeapSort(a, sizeof(a)/sizeof(HPDataType));
for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
printf("%d ", a[i]);
//Heap hp;
//HeapInit(&hp, a, sizeof(a) / sizeof(HPDataType));
return 0;
}
力扣 最小的k个数
面试题 17.14. 最小K个数 - 力扣(LeetCode)
但是过不了,不知道为什么
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void AdjustDown(int*a,int n,int root)
{
int parent=root;
int child=parent*2+1;
while(child<n)
{
if(child+1<n&&a[child+1]>a[child])
{
child++;
}
if(a[parent]<a[child])
{
int tmp=a[parent];
a[parent]=a[child];
a[child]=tmp;
parent=child;
child=parent*2+1;
}
else
{
break;
}
}
}
int* smallestK(int* arr, int arrSize, int k, int* returnSize){
*returnSize=k;
if(k==0)
return NULL;
int*retArr=(int*)malloc(sizeof(int)*k);
for(int i=0;i<k;i++)
{
retArr[i]=arr[i];
}
for(int i=(k-1-1)/2;i>=0;i--)
{
AdjustDown(retArr,k,i);
}
for(int j=k;j<arrSize;j++)
{
if(arr[j]<retArr[0])
{
retArr[0]=arr[j];
AdjustDown(retArr,k,0);
}
}
return retArr;
}