在上一篇博客中,我详细探讨了堆的创建与调整,这一篇基于上一篇(https://blog.csdn.net/xinger_28/article/details/82926744)的基础上讨论堆的插入与删除。
首先声明此堆为小堆。小堆与大堆代码相似,原理相似
小堆的插入:在已经建成的最小堆的后面插入要插入的新元素,插入之后,当节点不满足小堆的性质时,对对重新进行向下调整。
(关于为何用新元素插入最后,就我个人而言,是为了减少调整次数,毕竟若新元素放在后面恰巧满足堆的性质就不需要调整,总体而言,调整次数减少;若将新元素放在最前面或者任一位置,有非常大的概率破坏堆的完整性,可能需要对堆进行一次新的建立,个人观点,不喜勿喷。)
小堆的删除:删除时每次删除堆顶元素。
删除方法:
1)判断需要删除的元素所在位置是否存在,若不存在,结束;若存在,位置为K,则下一步。
2)将堆的最后一个元素代替要删除的元素,将堆的元素个数减少一个。
3)重新对堆进行调整,直到满足堆的性质。
代码如下:
头文件:二叉堆.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define Max 100
typedef int DataType;
//typedef int size_t;
//二叉堆
typedef struct StackN
{
DataType array[Max];
//size_t size;
int size;
}StackN;
void init(StackN * php)
{
php->size = 0;
php = NULL;
}
//让数据入堆
void CreatS(DataType a[], StackN*php, int n)
{
if (n == 0)
{
return;
printf("内容为空!\n");
}
int i = 0;
for (i = 0; i < n; i++)
{
php->array[i] = a[i];
php->size++;
}
}
void swap(int*a, int *b)
{
int t = 0;
t = *a;
*a = *b;
*b = t;
}
void AdJust(StackN*php, int root)
{
while (1) {
int left = 2 * root + 1;
int right = 2 * root + 2;
// 判断是否是叶子结点,如果左孩子下标越界了,没有左孩子了
// 所以也就没有右孩子了
if (left > php->size) { // == 的情况也是越界
// 越界
return;
}
int min = left; // 假设大的那个是左孩子
// 找到左右孩子中大的一个
// 一定要先判断右孩子有,才能比较左右孩子的大小
// if (array[right] > array[left] && right < size),错误的
if (right <= php->size && php->array[right] < php->array[left]) {
min = right;
}
// 判断和 [root] 的关系
// root >= max 错误的, root 和 max 表示的下标
if (php->array[root] <= php->array[min]) {
return;
}
// 交换
int t = php->array[root];
php->array[root] = php->array[min];
php->array[min] = t;
root = min;
}
}
void A_S(StackN*php)
{
int i = 0;
for (i = (php->size/2-1); i >= 0; i--)
AdJust(php, i);
printf("\n");
}
//堆的插入
void Insert(StackN*php, DataType data)
{
php->array[php->size] = data;
php->size++;
int i = 0;
for (i = (php->size-1) / 2 - 1; i >= 0; i--)
AdJust(php, i);
printf("\n");
}
//堆的删除
void Pop(StackN*php, DataType data)
{
int i = 0;
for (i = 0; i <php->size; i++)
{
if (data == php->array[i])
{
break;
}
}
if (i == php->size)
{
printf("堆中没有此元素\n");
return;
}
php->array[i] = php->array[php->size-1];
php->size--;
A_S(php);
printf("\n");
}
//打印堆
void Print(StackN*php)
{
int i = 0;
for (i = 0; i < php->size; i++)
printf("%d ", php->array[i]);
printf("\n");
}
void test()
{
StackN php;
init(&php);
DataType aa[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 }; //堆 调整为小堆
int n = sizeof(aa) / sizeof(DataType);
CreatS(aa, &php, n);
Print(&php);
A_S(&php);
Print(&php);
Insert(&php, 110);
Print(&php);
printf("加入成功\n");
Pop(&php, 78);
Print(&php);
printf("\n >");
Pop(&php, 55);
Print(&php);
}
源文件: test.cpp