堆的相关内容:
- 建堆:堆是利用一个数组来进行创建的
建堆的思路:堆分为大堆和小堆,建堆时是从最后一个根节点开始进行调整,假设左右结点的堆已经满足堆的性质,所以,每进行调整一次堆的根节点之后就要向下调整。
堆的删除:当然是进行头删,这样才具有挑战性,尾删不影响堆的性质。
- 头删:
- 1.把让第一个元素的值等于最后一个元素
- 2.进行向下调整
3.数组的大小减1
尾插:尾插需要判断插入的数冲洗构建而成的堆是否还满足堆的性质,采取向上调整
堆排序:1.升序->建大堆;降序->建小堆。2.建完堆之后每次进行把第一个数和最后一个数进行交换。然后把size-1-i个数从根节点开始进行向下调整,直到交换完所有的数(建堆,交换,调整)
以下为代码实现:
heap.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#define MAX_SIZE 100
typedef struct Heap{
int arr[MAX_SIZE];
int size;
}Heap;
//堆的初始化
void InitHeap(Heap * pH,int arr[],int size);
//堆的创建
void MakeHeap(Heap * pH);
//向下调整
void AdjustDown(Heap *pH,int root);
//交换
void Swap(int *p1, int *p2);
//打印
void print(Heap *pH);
//堆的尾插
void PushHeap(Heap * pH, int data);
//向上调整
void AdjustUp(Heap *pH, int child);
//堆的删除(头删,比较有意思)
void PopHeap(Heap *pH);
//堆排序
void HeapSort(int arr[],int size);
//大堆的向下调整
void MaxAdjustDown(int arr[],int size, int parent);
heap.c
#include"heap.h"
//堆的初始化
void InitHeap(Heap * pH, int arr[], int size)
{
assert(pH);
assert(pH->size);
memcpy(pH->arr, arr, sizeof(int)*size);
pH->size = size;
}
//堆的创建
void MakeHeap(Heap *pH)
{
int left,right,i;
for (i = (pH->size - 2) / 2; i >= 0; i--)
{
left = 2 * i + 1;
right = 2 * i + 2;
int minchild = left;
if (pH->arr[left] > pH->arr[right])
{
minchild = pH->arr[right];
}
if (pH->arr[i] > pH->arr[minchild])
{
Swap(pH->arr + i, pH->arr + minchild);
}
AdjustDown(pH,minchild);
}
}
//向下调整
1.递归
//void AdjustDown(Heap *pH,int parent)
//{
// int left = 2 * parent + 1;
// int right = 2 * parent + 2;
// int minchild = left;
// //是叶子结点的时候
// if (left >= pH->size)
// {
// return;
// }
//
// if (right <pH->size&&pH->arr[left] > pH->arr[right])
// {
// minchild = right;
// }
/*if (pH->arr[parent] <= pH->arr[minchild])
{
return;
}
Swap(pH->arr + parent, pH->arr + minchild);*/
// AdjustDown(pH, minchild);
//}
//2.循环
void AdjustDown(Heap * pH, int parent)
{
while (parent<pH->size){
//判断是否是叶子结点
int left = 2 * (parent)+1;
int right = 2 * (parent)+2;
if (left >= pH->size)
{
return;
}
//向下调整的过程是一个循环
int minchild = left;
if (right <pH->size&&pH->arr[left] > pH->arr[right])
{
minchild = right;
}
if (pH->arr[minchild] >= pH->arr[parent])
{
return;
}
Swap(pH->arr + minchild, pH->arr + parent);
parent = minchild;
}
}
void Swap(int *p1, int *p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void print(Heap *pH)
{
int i = 0;
for (i = 0; i < pH->size; i++)
{
printf("%d ", pH->arr[i]);
}
printf("\n");
}
//堆的尾插
void PushHeap(Heap *pH, int data)
{
assert(pH);
assert(0<pH->size<MAX_SIZE);
pH->arr[pH->size] = data;
pH->size++;
AdjustUp(pH, pH->size - 1);
}
//向上调整
1.递归
//void AdjustUp(Heap *pH, int child)
//{
// int parent = (child - 1) / 2;
// if (pH->arr[parent] <= pH->arr[child])
// {
// return;
// }
// Swap(pH->arr+parent, pH->arr+child);
//if (parent == 0)
//{
// return;
//}
// AdjustUp(pH, parent);
//
//}
//2.循环
void AdjustUp(Heap * pH, int child)
{
while (child >0)
{
int parent = (child - 1) / 2;
if (pH->arr[child] < pH->arr[parent])
{
Swap(pH->arr + parent, pH->arr + child);
}
if (parent == 0)
{
return;
}
child = parent;
}
}
//头删
void PopHeap(Heap * pH)
{
assert(pH);
pH->arr[0] = pH->arr[--pH->size];
AdjustDown(pH, 0);
}
//堆排序(建大堆的过程)
void HeapSort(int arr[],int size)
{
int i,j;
for (i = (size - 2) / 2; i >= 0; i--)
{
int left = 2 * i + 1;
int right = 2 * i + 2;
int maxchild = left;
if (right <size&&arr[left] <arr[right])
{
maxchild = right;
}
if (arr[maxchild]>arr[i])
{
Swap(arr + i, arr + maxchild);
MaxAdjustDown(arr, size, maxchild);
}
}
for (j = 0; j < size; j++)
{
Swap(arr, arr+size - 1 - j);
MaxAdjustDown(arr,size - j - 1,0);
}
}
//大堆的向下调整
void MaxAdjustDown(int arr[],int size, int parent)
{
int left = 2 * parent + 1;
int right = 2 * parent + 2;
int maxchild = left;
if (left >= size)
{
return;
}
if (right<size&&arr[left] < arr[right])
{
maxchild = right;
}
if (arr[parent]>arr[maxchild])
{
return;
}
Swap(arr + parent, arr+maxchild);
MaxAdjustDown(arr,size, maxchild);
}
main.c
#include"heap.h"
int main(void)
{
int arr1[9] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
int arr2[] = { 2, 0, 1, 8, 4, 6, 7, 9 };
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
Heap heap;
InitHeap(&heap, arr1, size1);
MakeHeap(&heap);
print(&heap);
PushHeap(&heap, 13);
PushHeap(&heap, 89);
print(&heap);
PopHeap(&heap);
print(&heap);
HeapSort(arr2,size2);
int i = 0;
for (i = 0; i < size2; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
}