The sequential structure and realization of binary tree
- 1. The sequential structure of the binary tree
- 2. The concept and structure of the heap
- 3. Simulation implementation of linear heap
-
- 3.1 The basic structure definition of the heap
- 3.2 Initialization of the heap
- 3.3 Destruction of the heap
- 3.4 Insertion of heap data
- 3.5 Heap Deletion
- 3.6 Determine whether the linear heap is empty
- 3.7 Finding the Number of Linear Heap Elements
- 3.8 Return the elements of the linear heap header
- 3.9 Printing the elements of a linear heap
1. The sequential structure of the binary tree
Ordinary binary trees are not suitable for storing in arrays, because there may be a lot of wasted space. A complete binary tree is more suitable for storage in a sequential structure. In reality, we usually store the heap (a kind of binary tree) using an array of sequential structures. It should be noted that the heap here and the heap in the virtual process address space of the operating system are two different things. One is the data structure and the other is the management system in the operating system. A region of memory is segmented.
2. The concept and structure of the heap
If there is a set of keys K = { k 0 , k 1 , k 2 ..., k n-1 }, store all its elements
in a one-dimensional array in the order of a complete binary tree, and satisfy: K i <= K 2*i+1 and K i <= K 2*i+2 ( K i >=
K 2*i+1 and K i <= K 2*i+2 ) i = 0, 1,
2 ..., is called a small heap (or large heap). The heap with the largest root node is called the max heap or the big root heap, and the heap with the smallest root node is called the min heap or the small root heap.
Quick description:
Big heap (big root heap): The father in the tree is greater than (equal to) the child.
Small heap (small root heap): The father in the tree is less than (equal to) the child.
Properties of the heap:
-
The value of a node in the heap is always not greater or less than the value of its parent node;
-
A heap is always a complete binary tree.
Application scenarios: heap sort, topk.
3. Simulation implementation of linear heap
3.1 The basic structure definition of the heap
typedef int HPDataType;//堆中存放的数据,假设是整型
typedef struct Heap
{
HPDataType* a;//指针指向堆中存储的数据
size_t size;//堆中当前元素的数目
size_t capacity;//堆中所能存储数据的容量
}HP;
3.2 Initialization of the heap
void HeapInit(HP* php)
{
assert(php);
php->capacity = php->size = 0;
php->a = NULL;
}
3.3 Destruction of the heap
void HeapDestory(HP* php)
{
assert(php);
free(php->a);
php->a = NULL;
}
3.4 Insertion of heap data
Ideas:
Time complexity: log(N)
void Swap(HPDataType* pa, HPDataType* pb)//交换函数:交换数组中的两个元素
{
HPDataType tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void AdjustUp(HPDataType* a, size_t child )//堆的向上调整
{
size_t parant = (child - 1) / 2;
while (child > 0)
{
if (a[child] < a[parant])//此处如果是<就是小堆,如果是>就是大堆
{
Swap(&a[child], &a[parant]);
child = parant;
parant = (child - 1) / 2;
}
else
{
break;
}
}
}
void HeapPush(HP* php, HPDataType x)
{
assert(php);
//判断是否需要扩充并进行扩充
if (php->size == php->capacity)
{
size_t newCapacity = php->capacity == 0 ? 2 : 2 * php->capacity;
HPDataType*tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType)*newCapacity);
if (tmp == NULL)
{
printf("realloc failed\n");
exit(-1);
}
php->a = tmp;
php->capacity = newCapacity;
}
php->a[php->size] = x;
php->size++;
//向上调整,控制保持是堆
AdjustUp(php->a, php->size - 1);
}
3.5 Heap Deletion
Ideas:
-
Swap the first number with the number in the last position
-
delete last data
-
adjust down
Below is an illustration of the downward adjustment:
Time Complexity: O(log 2 N)
void Swap(HPDataType* pa, HPDataType* pb)//交换函数:交换数组中的两个元素
{
HPDataType tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void AdjustDown(HPDataType* a, size_t size,size_t root)
{
size_t parant = root;
size_t child = 2*parant+1;
while (child<size)
{
if (child+1<size &&a[child + 1] < a[child])//此时后面的这个如果是<就是小堆,如果是>就是大堆
++child;
if (a[child] < a[parant])//如果是<就是小堆,如果是>就是大堆
{
Swap(&a[child], &a[parant]);
parant = child;
child = 2 * parant + 1;
}
else
{
break;
}
}
}
void HeapPop(HP* php)
{
assert(php);
Swap(&php->a[0], &php->a[php->size - 1]);
php->size--;
AdjustDown(php->a, php->size, 0);
}
Q: Why doesn't the deletion of the heap directly cover from the back to the front, and cover the first element?
Answer: First, the time complexity is O(N). Second, the original structure of the heap may be disrupted, and at the same time, the original properties of the heap may be lost and become no longer a heap, unless the original array elements of the heap are from small to large or from The properties of the heap can be maintained only when the big to the small is ordered, but even in this case the structure of the heap will still be disrupted, that is, their parent-child relationship will be destroyed.
3.6 Determine whether the linear heap is empty
bool HeapEmpty(HP* php)
{
assert(php);
return php->size == 0;
}
3.7 Finding the Number of Linear Heap Elements
size_t HeapSize(HP* php)
{
assert(php);
return php->size;
}
3.8 Return the elements of the linear heap header
HPDataType HeapTop(HP* php)
{
assert(php);
assert(php->size > 0);
return php->a[0];
}
3.9 Printing the elements of a linear heap
void HeapPrint(HP* php)
{
assert(php);
for (size_t i = 0; i < php->size; i++)
{
printf("%d ", php->a[i]);
}
printf("\n");
}