文章目录
前言
二叉树是一种重要的数据结构,其中每个节点最多有两个子节点:左子节点和右子节点。它常用于实现搜索算法、排序算法、数据存储和图形表示等。二叉树具有递归性,可以通过遍历算法(如前序、中序、后序和层次遍历)来访问其节点。学习和理解二叉树对于掌握更复杂的数据结构和算法至关重要。
堆
1.1 二叉树的概念
1.2 满二叉树和完美二叉树
满二叉树(Full Binary Tree):除了叶子节点外,每一个节点都有左右两个子节点的二叉树称为满二叉树。
完全二叉树(Complete BinaryTree):完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点必须靠左对齐,且不能有短,最后一层最少可以只有一个。
这不是一个完美二叉树
1.3 堆的概念
1.4 堆的性质
大堆:
小堆:
1.4 堆的实现
1.4.1堆的向上调整算法
这里给一组数据进行交换
int a[] = {10,15,56,25,30,70,5};
堆的向上调整算法代码实现:
void Swap(HPDataType* x,HPDataType* y)
{
HPDataType tmp = *x;
*x = *y;
*y = tmp;
}
void AdjustUp(HPDataType* a, int child)
{
int Parent = (child- 1) / 2;
while (child> 0)
{
if (a[Parent] > a[child])
{
Swap(&a[Parent], &a[child]);
child = Parent;
Parent = (child - 1) / 2;
}
else
{
break;
}
}
}
1.4.1堆的向下调整算法
这里给一组数据进行交换
int a[]= {}
堆的向下调整算法代码实现:
void Swap(HPDataType* x,HPDataType* y)
{
HPDataType tmp = *x;
*x = *y;
*y = tmp;
}
void AdjustDown(HPDataType* a, int n, int Parent)
{
// 这里可以使用假设法
int child = Parent * 2 + 1;
while (child < n)
{
// 假设法这个位置需要进行判断是否是小的哪个孩子,不是则需要进行更新
if (a[child] > a[child + 1] && child + 1 < n)
{
child += 1;
}
if (a[Parent] > a[child])
{
Swap(&a[Parent], &a[child]);
Parent = child;
child = Parent * 2 + 1;
}
else
{
break;
}
}
}
1.4.1堆的接口实现
1.4.1.1堆的初始化
typedef int HPDataType;
typedef struct Heap
{
HPDataType* _a;
int _size; // 堆顶的下一个位置的下标
int _capacity;// 堆的空间
}Heap;
// 堆的初始化
void HeapInit(Heap* hp)
{
assert(hp);
hp->_a = NULL;
hp->_capacity = hp->_size = 0;
}
1.4.1.2堆的销毁
void HeapDestroy(Heap* php)
{
assert(php);
free(php->_a);
php->_a = NULL;
php->_size = php->_capacity = 0;
}
1.4.1.3堆的插入
void HeapPush(Heap* php,HPDataType x)
{
assert(php);
if (php->_capacity == php->_size)
{
int newcapacity = php->_capacity == 0 ? 4 : php->_capacity * 2;
HPDataType* new_a = (HPDataType*)realloc(php->_a,newcapacity*sizeof(HPDataType));
if (new_a == NULL)
{
perror("HeapPush()::realloc() fail!!");
return;
}
php->_capacity = newcapacity ;
php->_a = new_a;
}
php->_a[php->_size++] = x;
AdjustUp(php->_a, hp->_size - 1);
}
1.4.1.4堆的删除
void HeapPop(Heap* php)
{
assert(php && php->_size > 0);
Swap(&php->_a[0],&php->_a[php->_size - 1]);
php->_size--;
AdjustDown(php->_a, php->_size, 0);
}
1.4.1.4堆的判空
int HeapEmpty(Heap* php)
{
assert(php);
return php->_size == 0;
}
1.4.1.4 获取堆的数据个数
void HeapSize(Heap* php)
{
assert(php);
return php->_size;
}