[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation — C Sequential Structures)

Time:2023-10-24

=========================================================================

Relevant code gitee self retrieve

C Learning Diary: Work Harder (gitee.com)

 =========================================================================

follow up on previous period

[Data Structure Primer] VI. Queues in Linear Tables (Chained Structure Implementation of Queues) – Blogs

 =========================================================================

                     

1 . Tree in a nonlinear table

The concept and structure of trees:

            

Tree concepts

The treeis annonlinear (math.)data structure
it isby n(n>=0) finite number of nodescreateset with hierarchical relationship
replantIt’s called a tree.It’s because itIt looks like an upside down tree.That means it’sroot side upbut (not)leaf arrangementThe.
( jie pointlinear structurejoint  ;nonlinear structurenodal )

               

Tree structure

  • There is aspecial nodeknown asroot noderoot nodeNo predecessor node
                 
  • except for the root nodeRemaining nodesbetenths M(M>0) adisjoint sets T1 、T2 、……Tm ,
    included among theseEvery collection Ti(1<= i <= m) againA subtree with a structure similar to a tree
    Root node of each subtreeThere’s one and only one.precursor nodeThere can be zero or moresuccessor node
                   
  • The treeisrecursive (calculation)definethe
                 
  • tree structureMiddle.There can be no intersection between subtreesOtherwise it’s not a tree structure
Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                

Other related concepts of trees:

(Some of the concepts are not well understood in terms of their corresponding meaningsYou can.Look at the following examples in conjunction with the sample diagram)

concept nameequivalent meaningExample in the figure below
Degree of nodesanThe node containsthesubtree number call sth (by a name)The degree of this nodeNode AThe degree of 6
leaf node
(end node)
Degree 0thenodal call sth (by a name)leaf nodeNode BCH…… is a leaf node

branch node
(non-terminal node)

Degree not 0thenodal call sth (by a name) branch nodeNode DEF…… is the branch node
parent node
(parent node)
ifA node contains children
Then this node call sth (by a name)The parent of its children
Node AisNode Bparent of
child node
(child node)
a nodeThe root node of the subtree containing call sth (by a name) Children of this nodeNode BisNode Achild node of
sibling nodeNodes with the same parent mutually agreed upon sibling nodeNode BCis a brother node
Tree DegreesIn a treeThe degree of the largest nodecall sth (by a name)Tree DegreesThe tree in the figure belowThe degree of 6
Hierarchy of nodesDefine from the root
The rootforLevel 1(0)child node of the rootforsecond (i)
in a similar fashionIt is recommended to count from the first levelThe empty tree can be represented by the zero level
Layer where node A is locatedfor the first tier.
Layer where node B is locatedFor the second layer ……
Height of the tree
(Depth of the tree)
treeMaximum level of a nodeThe tree in the figure belowThe height (depth) of 4
Cousin Nodeparent node(parent node)Nodes in the same layer mutually agreed upon father’s brother’s sonsNode HIsibling node
Ancestors of nodesFrom the root to all the branch nodes on that nodeall forebearsNode Ais the ancestor of all nodes
posterityAny node in a subtree with a node as root
call them all The children of this node
All nodes areNode Adescendant
deforestationbyThe set of m (m>0) trees that do not intersect each other call sth (by a name) deforestation
Example diagram:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                     

                    


                    

Tree storage (representation):

                  

Tree representation:

  • tree structurecounterpartlinear tableIt’s more complicated.It’s done. It’s done.stockpileindicate(after a verb) indicating the beginning and continuation of an action or a stateitmore trouble than it’s worthOh, yeah.
    both… and…Save Value Fieldas wellPreserve the relationship between nodes and
                      
  • in practiceThe treeThere are many ways to expressAs:
    parental representationchild representationChild Biparental Representationas well asChild Brother Representationetc.
    We’re right here.A brief look at one of themost commontheOn the leftkidrightFraternization
    Optimal Design of Tree Structures

                          

(Left) Child (right) Structure of the brother representation:

The type of data stored in the data fields of each node in the // tree:
                     typedef int DataType;

                     // (left) child (right) brother representation:
                     struct TreeNode
                     {
                         //Data field in the node:
                         DataType data;

                         // First child node -- the leftmost child node:
                         struct TreeNode* firstchild;

                         // Points to the next sibling node of this node -- the right sibling:
                         struct TreeNode* nextbrother;
                     };

                

This representation essentially implements a tree with a linked list:
  • firstchild pointer on a gauge — Equivalent topointer to the head of a linked listFind the head node one level below the current node
                    
  • nextbrother pointer on a gauge — Equivalent toChained table traversal pointersYou can.Traverse backward through the nodes of the layer
                     
Use the example chart:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

               

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2 . Binary Tree in Tree

Concept and structure of binary tree:

            

The concept of binary trees

A binary treeisA finite set of nodescollectionfulfillment

  • orempty
  • or byanroot nodeon top of thatTwo trees calledleptotree (math.)andright subtree (math.)thebinary treemake up

             

Structure of a binary tree

  • binary treenon-existentNodes with degree greater than 2
    (so)Degree of nodeslikelihoodis0 namely, an empty tree (i.e. not a tree)It could also be1 or2 )

                     
  • Subtrees of a binary treeThere arethe difference between right and leftThe order cannot be reversed.ThereforeBinary trees are ordered trees
Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

               

Caution:

with regards toArbitrary binary tree
allCompounded by the following

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                     

                    


                    

Special binary trees

                   

full binary tree (math.)

anbinary treeIfThe number of nodes in each layer is maximizedfollowThis binary tree is a full binary tree
That is, ifHeight of a binary treefor k andTotal number of nodesbe2^k – 1followIt’s a full binary tree.

Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                     

                     

complete binary tree (math.)

complete binary tree (math.)isVery efficient data structuresThe complete binary tree isbyfull binary tree (math.)Concepts elicited
with regards tohigh degreefor K of which there are n nodesthebinary tree
if and only ifitsEvery nodeallWith a height ofK thefull binary tree (math.)in the numbering from 1 to n The nodes of the one-to-one correspondencewhen
known as…complete binary tree (math.)
          

Simple to understand.

suppose that…Height of the treebeK ,before K-1 layeris“Full”
The last layer may not be full.At least one node), andTree from left to rightisprogressionthe
theThe tree is a complete binary tree

                  

Notes:

full binary tree (math.)isA special kind of complete binary tree

The last layer of a complete binary treesatisfynamelyis a full binary tree

so let’s sayHeight of a complete binary treeforK ,
Highest total number of nodesbe2^K – 1  ;Minimum total number of nodes(The last layer has only one node) is2^(K – 1) 

                 

Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                     

                    


                    

Storage structure of a binary tree

                 

binary treeIt’s generally possible toUse two structures to store
one kind ofsequential structurekind ofchain structure

              

sequential structure

  • sequential structure storagejust likeutilizationarrays to store
    Any positionBy subscriptingcanFind the father.orkidIn the arrayElement with subscript 0namelyroot node

                   
  • Using arrays for storageIt is generally only appropriate to expresscomplete binary tree (math.)full binary tree (math.)),
    on account ofIf it’s not a complete binary tree there will beWaste of space
                      
  • In real life useonly ifThe heap only thenUse arrays to store
                            
  • sequential storage in binary treeinphysicallyisAn arrayinlogicallyisA binary tree.
                        
Sequential structural (mathematical) laws:
  • pass (a bill or inspection etc)parent nodesuffixlocatechild nodesuffix):
    left node  ==》  leftchild  =  parent * 2 + 1
    right node  ==》  rightchild  =  parent * 2 + 2

                   
  • pass (a bill or inspection etc)child nodesuffixlocateparent nodesuffix):
    parent node  ==》 parent  = (child – 1) / 2
    Observation reveals thatleft node subscriptallodd numberright node subscriptalleven number
    (even-1) / 2willround downGet even parent node subscripts
    the reason whyA formula to find the parent node
                   
  • lawonly applicable tocomplete binary tree (math.)Becausecomplete binary tree (math.)It’s continuous from left to right.
    incomplete binary treeIt is also possible to use theLibyan Arab JamahiriyaBecause nodes are not necessarily consecutive
    the reason whySome locations in the array do not store elementslead tosquandering of space
Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3 . Heap in a Complete Binary Tree

Concept and structure of a heap

          

The concept of a heap

If there is aA collection of keycodes  [Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures) ,
classifier for objects with a handleAll its elementsAccording to theThe sequential storage of a fully binary tree is stored in aone-dimensional arrayIn thefulfillment

  • [Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures) and [Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

    ( [Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)and [Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

    included among thesei = 012……

thecall sth (by a name)small pileorlarge amount
  • willLargest heap of root nodesbe known asMaximum stackora big pile of rootslarge amount
  • Heap with smallest root nodebe known asminimum heaporrootletsmall pile

              

Simple to understand:

small pile— Value of each parent nodeis always less than or equal toThe value of its child nodeValue of each child nodeAlways greater than or equal toThe value of its parent node
large amountValue of each parent nodeAlways greater than or equal toThe value of its child nodeValue of each child nodeis always less than or equal toThe value of its parent node

              

Structure of the heap

  • The value of a node in the heapAlways no greater or no less thanThe value of its parent node
                  
  • The heapalwaysA complete binary tree
Illustration:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

4 . Heap implementation

Implementing a Heap Using the Sequential Structure of a Binary Tree

  • Ordinary binary treeandunsuitablearrayssequential structureto storeBecauseThere will be a lot of wasted space
                 
  • whilecomplete binary tree (math.)moreserviceabilitysequential structurestockpile
    the reason whyIn reality, it is common to putThe heapA complete binary treeutilizationArrays of sequential structuresto store

                    
  • needattention (heed)Yes.Here’s the heapandHeap in the address space of an operating system virtual processtwo quite different things
    one isdata structureone isA segment of an area of the operating system that manages memory
                     

(Detailed explanations are in the notes to the pictures, and the code subfile is placed under a heading)

                             

Preparation for the realization of specific functions

  • instack header fileIncludes the header files required afterward
                  
  • definenodal value(bottom-of-heap array element(used for emphasis)typology
                  
  • Defining Heap Types
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapInit function — initializes members of the heap type

  • assertReceived heap type pointer is not null
                   
  • willHeap root pointerSet to NULL
    generalCurrent number of nodes in the heapSet to 0
    generalSpace units currently opened by the heapSet to 0
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapDestroy function — performs destruction on the heap type

  • assertReceived heap type pointer is not null
                   
  • liberate (a prisoner)Dynamic space in the heap type opened with a as header
                  
  • willCurrent number of nodes in the heapandSpace units currently opened by the heapSet to 0
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapPrint function — prints the value of each node in the heap

  • assertReceived heap type pointer is not null
                   
  • utilizationfor loopcyclic printing
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

Swap function — swaps node positions in an up-down adjustment operation.

  • upward adjustmentAdjustUp Internal Functions(math.) andDownward AdjustmentAdjustDown internal functionisin
    push in a nodeHeapPush function(math.) andHeap Deletion NodesHeapPopImportant steps in the operation
    (indicates contrast)inAdjustment upward operationandDownward Adjustment OperationIn therequireSwap functionExchanging two node values
                   
  • The function is simple to implement.Create a temporary variable to swap the two node values.can immediately (do sth)
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

AdjustUp Internal Functions

Used to adjust the position of a node in the heap upwards after it has been inserted (HeapPush function)

  • pass (a bill or inspection etc)on top ofsequential structureThe formulas taught in
    pass (a bill or inspection etc)Subnode subscript childlocateIts parent node subscript parent
                   
  • utilizationwhile loopMake upward adjustments
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

(Hard) HeapPush function — inserts a node into a heap type

  • assertReceived heap type pointer is not null
                   
  • post assertionDetermine if capacity expansion is neededfailing agreementPerform capacity expansion operationsandCheck if the expansion is successful
                  
  • After enough spacePutting the inserted node into the heap
    insertedCurrent number of nodes in the heap size++
                    
  • After inserting a nodecall (programming) upward adjustmentAdjustUp Internal Functions
    Adjustment of the position of the inserted node in the heap
    feasibleThe whole thing is still a heap after insertionLarge or small piles
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapInitArray function — takes an array and initializes it to a heap base array.

  • realizationtheUpward Debugging AdjusuUp Internal FunctionsLater.
    canUse it to build pilesIt’s up to you whether you build a big pile or a small one.within AdjustUp functioncondition setting),
    compared with the previoustheHeapInit initialization function
    This function willOpen dynamic space directly for the heapmergePut in the values of each node
                   
  • assertReceived heap type pointer is not null
    assertArray a is not empty
                  
  • Opening up dynamic spacesandInspection of openings
                    
  • willCurrent number of nodes in the heapSet to n
    generalSpace units currently opened by the heapSet to n
                        
  • willElements of array aCopy as heap bottom array element
                   
  • againcirculateupward adjustmentNodes in the heapunderlying array elementPerform pile building
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

AdjustDown internal function

Used to adjust the heap downward after removing the root node (HeapPush function) so that it is still a heap

  • pass (a bill or inspection etc)on top ofsequential structureThe formulas taught in
    pass (a bill or inspection etc)The parent node subscript parentlocateIts left child node subscript child

                   
  • utilizationwhile loopCycle down the adjustment heapTake a small pile as an example
                  
  • inwhile looppriorfind outThe current two children of thesubscript of a smaller child node
                    
  • inwhile loopAfter finding the smaller node subscript
    Determine if a downward adjustment is requiredexecute the corresponding operation
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

(Difficult) HeapPop function — removes the root node of the heap type (removes the most current value in the heap)

  • assertReceived heap type pointer is not null
    assertNumber of heap nodesNumber of elements in the underlying arrayNot 0
                   
  • utilizationSwap node Swap functionSwap the root node value with the tail node value
    deutero-Remove the original root node that was moved to the end.
                  
  • utilizationAdjustDown internal functionDownward adjustment of the heap
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapTop function — gets and returns the push root node value

  • assertReceived heap type pointer is not null
    assertNumber of heap nodesNumber of elements in the underlying arrayNot 0

                   
  • straightforwardReturns the root node value
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapEmpty function — determines whether the heap type is empty or not

  • assertReceived heap type pointer is not null
                   
  • in the event thatNumber of heap nodesNumber of elements in the underlying arrayA value of 0 indicates that the heap is empty
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

Overall test:

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

            

            

———————————————————————————————

            

HeapSort sort function (hard)

Sorting ordinary arrays (ascending or descending) using downward-adjusting operations in the heap

  • build up a pile
    The array to be sortedThink of it as a complete binary tree.
    utilizationLoop down adjustment operationFrom the penultimate parent nodenon-leaf nodeBeginning of downward adjustment
    After completion of adjustmentsarrayswouldConsistent with the nature of a heap(Here’s an example of a small pile)
    ascending ordercreate a big pile        ;        descending ordercreate a small pile
                   
  • arrange in order
    utilizationwhile loopsort
    classifier for objects with a handleminimum valueroot node of a small heap(math.) andtail elementcarry out an exchange

    theValues other than the minimumlook upon as a pilecarry outDownward AdjustmentSelection of sub-size values
    settheLast valueLoop again to adjust the next
icon

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

[Data Structures] Binary Trees in Nonlinear Tables (Heap Implementation -- C Sequential Structures)

                

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                

5 . Corresponding code

Heap.h — header file

#pragma once

// Include the required header files afterward in the heap header file:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>


// Define the type of the node value (the array element at the bottom of the heap):
typedef int HPDataType;

// Define the heap type:
typedef struct Heap
{
	// Because the underlying implementation is in a sequential structure.
	// So the type is similar to a sequential table:

	// Pointer to a heap node:
	// (points to the first element of the array at the bottom of the heap)
	HPDataType* a;

	// The current number of nodes in the heap:
	// (number of elements in the array at the bottom of the heap)
	int size;

	// The unit of space currently opened by the heap:
	// (units of space dynamically opened by the array at the bottom of the heap)
	int capacity;

}HP; // Heap type Heap renamed to HP



// heap initialization function 1 -- initializes members of the heap type
// Receive pointer to heap type (php)
void HeapInit(HP* php);

// Heap Destruction Functions -- Destruction of Heap Types
// Receive pointer to heap type (php)
void HeapDestroy(HP* php);

// Print the heap function -- prints the values of the nodes in the heap.
// Receive pointer to heap type (php)
void HeapPrint(HP* php);

// Node Position Swap Function -- Swaps node positions in an up-down adjustment operation:
// Receive pointers to the two nodes to swap places (p1 and p2)
void Swap(HPDataType* p1, HPDataType* p2);

// Heap insertion function -- inserts a node into a heap type
// Receive pointer to heap type (php)和插入节点的值(x)
void HeapPush(HP* php, HPDataType x);

// Heap Initialization Function 2 -- Receives an array to initialize it to a heap base array.
// Receive pointer to heap type (php)、数组首元素地址(a)、数组元素个数(n)
void HeapInitArray(HP* php, int* a, int n);

// Heap Delete Function -- Deletes the root node of the heap type (deletes the most current value in the heap)
// Receive pointer to heap type (php)
void HeapPop(HP* php);

// top-of-heap function -- gets and returns the push root node value
// Receive pointer to heap type (php)
HPDataType HeapTop(HP* php);

// Empty function -- determines if the heap type is empty.
// Receive pointer to heap type (php)
bool HeapEmpty(HP* php);

            

            

———————————————————————————————

                

Heap.c — implementation file

#define _CRT_SECURE_NO_WARNINGS 1
// Contains the heap header file:
#include "Heap.h"
// heap initialization function 1 -- initializes members of the heap type
// (no value is given at first, then a function is used to insert values to form a heap)
// Receive pointer to heap type (php)
void HeapInit(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// (Ensure that there is successful creation of heap types that can be initialized)
assert(php);
// Set the heap root node pointer to NULL:
php->a = NULL;
// Set the number of current nodes of the heap to 0:
php->size = 0;
// Set the heap's current unit of open space to 0:
php->capacity = 0;
}
// Heap Destruction Functions -- Destruction of Heap Types
// Receive pointer to heap type (php)
void HeapDestroy(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// Ensure that there are heap types that can be destroyed
assert(php);
// Free the dynamic space in the heap type opened with a as the header:
free(php->a);
// Set the current number of nodes in the heap and the current unit of space opened by the heap to 0:
php->a = NULL;
php->size = php->capacity = 0;
}
// Print the heap function -- prints the values of the nodes in the heap.
// Receive pointer to heap type (php)
void HeapPrint(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// (Make sure there is a successful creation of a heap type that can be printed)
assert(php);
// Loop printing using a for loop:
for (int i = 0; i < php->size; i++)
//size prints as many node values as there are nodes:
{
// Print node values by subscript:
printf("%d ", php->a[i]);
}
// Line breaks:
printf("\n");
}
// Node Position Swap Function -- Swaps node positions in an up-down adjustment operation:
// Receive pointers to the two nodes to swap places (p1 and p2)
void Swap(HPDataType* p1, HPDataType* p2)
{
// Create a temporary variable to cooperate in swapping the two node values:
HPDataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
// Implement an externally undeclared AdjustUp function internally.
// The first parameter receives the address of the first element of the bottom array of the heap.
//Second parameter receives the subscript of the just inserted array element (child node).
void AdjustUp(HPDataType* a, int child)
{
//Using the formulas mentioned earlier.
// Find the parent node subscript by its child node subscript:
int parent = (child - 1) / 2;
// Continue to adjust upwards as long as child is still greater than 0
// The subscripts of the upper nodes are smaller if they need to be adjusted upwards.
// So the child keeps getting smaller and smaller as it adjusts.
while (child > 0)
{
// Upward adjustment in small stacks:
if (a[child] < a[parent])
//Smaller heap with child node values smaller than the parent node values::
// In the big heap then the condition is changed to:
//if (a[child] > a[parent]) //upward adjustment for large piles
{
//Then the two would need to be switched.
Swap(&a[child], &a[parent]); 
After //Value substitution is successful, the subscripts are also adjusted:
//child is subscripted to parent subscript after moving to the upper level:
child = parent;
//child may also be a child of a parent node further up the hierarchy after it is moved to that level.
// It may need to be adjusted upwards again, at worst moved to become the root node of the heap:
// Get the subscript of the new parent again:
parent = (parent - 1) / 2;
}
else
// If the value of the child node in the mini-heap is already greater than or equal to the value of the parent node
//that is, it qualifies as a small heap
{
// Then there is no need to make upward adjustments, break exits the loop:
break;
}
}
}
// Heap insertion function -- inserts a node into a heap type
// Receive pointer to heap type (php)和插入节点的值(x)
void HeapPush(HP* php, HPDataType x)
{
//assert asserts that the received heap type pointer is not null:
// Make sure there are heap types to insert nodes into
assert(php);
// Check if expansion is needed after assertion:
if (php->size == php->capacity)
//Number of current nodes in the heap == units of open space.
//State that expansion is required before inserting a node:
{
// Create a variable to store the new capacity unit:
int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
// Because capacity is initialized to 0, it can be augmented using the trinomial operator:
//ps->capacity == 0 ? 4 : ps->capacity * 2
// if 0 then directly increase capacity to 4, if not 0 then increase capacity 2 times
// Open up dynamic space:
HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newCapacity);
// Here the realloc function is used directly for dynamic space opening.
// If the realloc function receives the header pointer (the first argument to the function) as null, the
// Then it is equivalent to the malloc function
//Checks on opening space:
if (tmp == NULL)
// Returns a null pointer and fails to open:
{
// Print the error message:
perror("realloc fail");
// Terminate the program:
exit(-1);
}
//After successfully opening the space, assign the header pointer of the opened space to a:
php->a = tmp;
// Assign the new capacity unit to the original capacity unit:
php->capacity = newCapacity;
}
// Perform insertion operations in the heap:
// Heap:
// Physical structure is an array; logical structure is a tree.
//Tree would have no concept of header and tail plugs
//Where exactly the node is inserted depends on the situation
// As long as the inserted value is large enough or small enough, you can keep replacing it one level up
//nodes inserted into the heap are to remain still a heap, a tree continuous from left to right
// Whatever the case, default to inserting the very end first:
// (i.e., the end of the array at the bottom of the heap)
// because the array subscripts start at 0.
// So size is the end insertion node subscript:
php->a[php->size] = x;
// Number of current nodes in the heap after insertion size++:
php->size++;
// At this point, if the insertion node is large enough (or small enough), the
// then the condition for a large (or small) heap is just satisfied, the
// but if it is not satisfied, adjust the insertion node towards the upper level of the tree, the
// and that it will be performed again afterwards.
// So here you can define an AdjustUp function inside the file.
// and make the call:
AdjustUp(php->a, php->size-1);
// The first parameter receives the address of the first element of the bottom array of the heap.
//Second parameter receives the subscript of the just inserted array element (child node).
// php->size-1 -- size++ after insertion of nodes in front of it
// So the subscript here should be -1 to get the subscript of the inserted element.
}
// Heap Initialization Function 2 -- Receives an array to initialize it to a heap base array.
// (gives you the individual values of the underlying array, which are then adjusted upwards to form the heap)
// Receive pointer to heap type (php)、数组首元素地址(a)、数组元素个数(n)
void HeapInitArray(HP* php, int* a, int n)
{
//assert assert asserts that the received heap type pointer is not null:
// (Ensure that there is successful creation of heap types that can be initialized)
assert(php);
//assert asserts that the array a is not empty:
assert(a);
// Open up dynamic space:
php->a = (HPDataType*)malloc(sizeof(HPDataType*) * n);
//Checks on opening space:
if (php->a == NULL)
// Returns a null pointer and fails to open:
{
// Print the error message:
perror("realloc fail");
// Terminate the program:
exit(-1);
}
// Set the number of current nodes of the heap to n:
php->size = n;
// Set the unit of space currently opened by the heap to n:
php->capacity = n;
// Make a copy of the array element as a heap bottom array element:
memcpy(php->a, a, sizeof(HPDataType) * n);
// Re-loop to adjust the nodes in the heap (the underlying array elements) upwards to build the heap :
for (int i = 1; i < n; i++)
{
AdjustUp(php->a, i);
}
}
// Implement an internally undeclared AdjustDown function.
// The first parameter receives the address of the first element of the bottom array of the heap.
// The second parameter receives the number of heap nodes (the number of elements in the underlying array).
//The third parameter receives the subscript of the root node (the original tail node) after the swap.
void AdjustDown(HPDataType* a, int n, int parent)
{
//(In small heaps) downward adjustments are needed to get child nodes that are smaller than the parent parent:
// (This child node should be switched with its parent)
// You can start by assuming that the left child node is smaller than the parent:
// Get the left child (first child) subscript of the root node:
int child = parent * 2 + 1;
// Worst case: root node becomes a leaf (no more children to replace)
while (child < n)
// left child node subscript if >= number of heap nodes (number of underlying array elements)
//Indicates that the array is out of range, and the parent node has become a leaf and can no longer be switched.
{
//If we are wrong in our assumptions above:
if (child + 1 < n  &&  a[child + 1] < a[child])
// In the big heap then the condition is changed to:
//if (child + 1 < n && a[child + 1] > a[child]) //downward adjustment for large piles
// child+1 is the subscript of the right child.
/* Compare the smaller node only if both left and right children exist:	
Prevent non-existent right child nodes from crossing boundaries: child + 1 < n
The above can enter the while loop as long as the left child node is in the array
And the left child node is probably the last element of the array
It may happen that the left child node exists but the right child node does not exist
So to compare smaller nodes in the presence of right child nodes
/No right child node directly uses the left child node.
*/
// If the right child node is smaller than the left child node:
{
// To get the right child node (smaller child node) subscript:
++child; // self-incremented, i.e., right child node subscripts
}
// Get the subscript of the smaller node by this point:
// (doesn't care if it's a left or right child node, just the node with the smaller value)
// (in a small heap) if the smaller node is smaller than the parent node
if (a[child] < a[parent])
// In the big heap then the condition is changed to:
//if (a[child] > a[parent]) //downward adjustment of large heaps
{
// Then the two need to be switched:
Swap(&a[child], &a[parent]);
// After swapping the two node values, the subscripts should also be refreshed:
parent = child;
// At this point the new child node is subscripted:
child = parent * 2 + 1;
}
else
// If the smaller node is already larger than the parent:
{
// That qualifies as a small pile, no need to switch:
break; //exit the loop
}
}
}
// Heap Delete Function -- Deletes the root node of the heap type (deletes the most current value in the heap)
// Receive pointer to heap type (php)
void HeapPop(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// Ensure that there are heap types available to delete the root node
assert(php);
//assert asserts that the number of heap nodes (the number of underlying array elements) is not zero.
// Ensure that there are nodes available for deletion:
assert(php->size > 0);
/*
If a move is made to overwrite the root node of the first position
It will cause the remaining node relationships to be messed up (brother to father to son)
The end result may not always be a heap that
And moving overrides in arrays is inherently inefficient
So it is possible to swap the root and tail nodes
A further tail deletion realizes the deletion of the root node
and the tail deletion in the array is more efficient.
*/
// Swap the root node value with the tail node value:.
Swap(&php->a[0], &php->a[php->size - 1]);
// &php->a[0] : root node value
// &php->a[php->size - 1] : tail node value
// Then delete the original root node that was moved to the end:
--php->size; // just direct the number of elements size-1
/*
At this point the structure of the left and right subtrees of the heap remains unchanged
Left and right subtrees are still small piles (big piles)
With this premise downward adjustments can be made:
Because the root and tail nodes swap places in front
So now the root node (the original tail node) may have to be larger than the starting child node
The tree as a whole does not qualify as a small heap, so a downward adjustment is made
(Note: Upward adjustment assumes that the preceding node qualifies as a heap)
Adjust the operation downward:
After becoming a root node, compare it with its two children
If the child nodes are smaller, swap positions
Swap positions and then compare with the next level of child nodes
If the child nodes are smaller, swap positions
And so on, at worst until it becomes a leaf
(Larger values in the smaller pile move down, smaller values go up)
*/
// So here you can define a downward adjustment function AdjustDown inside the file.
// and make the call:
AdjustDown(php->a, php->size, 0);
// The root node is subscripted 0 in the underlying array
/*
* :: Meaning and examples of the function:
The meaning of this function is to remove the first smallest value (in a small heap)
Then find the second smallest value, and so on, you can find the smallest value of the array in turn
Example: "Top 10 cake stores in the city" Small pile of root elements on the first good store that
Find the second best store after using this function and so on ......
*/
/*
* Time complexity of the function:
The downward or upward adjustment operation is performed 1 time in the best case and the height of the tree in the worst case.
I.e., time complexity is O(logN), and a billion values need to be adjusted only 30+ times -- excellent!
(log -- defaults to 2)
*/
}
// top-of-heap function -- gets and returns the push root node value
// Receive pointer to heap type (php)
HPDataType HeapTop(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// Ensure that there is a heap type available to get the root node value
assert(php);
//assert asserts that the number of heap nodes (the number of underlying array elements) is not zero.
// Make sure there are nodes in the heap type:
assert(php->size > 0);
// Return the root node value directly:
return php->a[0];
}
// Empty function -- determines if the heap type is empty.
// Receive pointer to heap type (php)
bool HeapEmpty(HP* php)
{
//assert asserts that the received heap type pointer is not null:
// Ensure that there is a heap type available to get the root node value
assert(php);
// If the number of heap nodes (number of elements in the underlying array) is 0 then the heap is empty:
return php->size == 0;
//php->size = 0 -- establishment returns true, heap is empty
//php->size = 0 -- return false if not true, heap is not empty 
}

            

            

———————————————————————————————

                

Test.c — test file

#define _CRT_SECURE_NO_WARNINGS 1
// Contains the heap header file:
#include "Heap.h"
// Test function -- unordered
void Test0()
{
//Create an array to create the values of the nodes to be placed in the heap.
int a[] = { 65,100,70,32,50,60 };
// Calculate the length of the array:
int alength = sizeof(a) / sizeof(int);
// Create a heap type variable:
HP hp;
// Initialize using the HeapInit function:
HeapInit(&hp);
// Use a for loop to put each value of the array into a heap type variable:
for (int i = 0; i < alength; i++)
{
// The heap type variable hp is just a full binary tree before there is a HeapPush.
// after insertion and sorting with the HeapPush function it becomes a heap.
// So one way to build a heap is to always push:
// Insert nodes using the HeapPush function:
HeapPush(&hp, a[i]);
}
printf("Current Heap:> ");
// Print the heap using the HeapPrint function:
HeapPrint(&hp);
// Use the HeapEmpty function to determine if the heap is empty:
while (!HeapEmpty(&hp))
// Get the heap root node value if it is not null:
{
// Use the HeapTop function to get the heap root node value and print it:
printf("Current heap root value: > %d\n", HeapTop(&hp));
//(in a small heap) using the HeapPop function to delete the current root node.
// and set the second smallest node as the new root node:
HeapPop(&hp);
}
// Destroy using the HeapDestroy function:
HeapDestroy(&hp);
}
Test function -- sorting
//
Heap sort function (before optimization) - sorts a normal array (ascending or descending) using the heap type
First parameter: address of the first element of the array at the bottom of the heap.
Second parameter: the number of elements in the bottom array of the heap.
//void HeapSort(int* a, int n)
//{
//	// Create a heap type variable:
//	HP hp;
//
//	// Initialize using the HeapInit function:
//	HeapInit(&hp);
//
//	// Use a for loop to put each value of the array into a heap type variable:
//	for (int i = 0; i < n; i++)
//	{
//		// The heap type variable hp is just a full binary tree before there is a HeapPush.
//		// after insertion and sorting with the HeapPush function it becomes a heap.
//		// So one way to build a heap is to always push:
//
//		// Insert nodes using the HeapPush function:
//		HeapPush(&hp, a[i]);
//	}
//
//	//printf("Current Heap:> ");
// Print the heap using the HeapPrint function:
//	//HeapPrint(&hp);
//
//	int i = 0;
//	// Use the HeapEmpty function to determine if the heap is empty:
//	while (!HeapEmpty(&hp))
//		// Get the heap root node value if it is not null:
//	{
//// (in a small heap) Assign the root node value of the heap type to the array a, in order.
//// Use the heap implementation to sort the array from smallest to largest:
//		a[i++] = HeapTop(&hp);
//
//		//(in a small heap) using the HeapPop function to delete the current root node.
//		// and set the second smallest node as the new root node:
//		HeapPop(&hp);
//	}
//
//	// Destroy using the HeapDestroy function:
//	HeapDestroy(&hp);
//}
Flaws in this sorting:
1. There has to be a heap data structure first.
2. Consumption of space complexity
//void Test1()
//{
//// Create a heap bottom array -- node values are randomized; unsorted
//	int a[] = { 65,100,70,32,50,60 };
//
//	// Calculate the length of the array:
//	int alength = sizeof(a) / sizeof(int);
//
// printf("Array before applying heap sort:> ");
//// Apply the array before the heap sort:
//	for (int i = 0; i < alength; i++)
//	{
//		printf("%d ", a[i]);
//	}
//	printf("\n");
//	
//// Use the HeapSort function to sort the unsorted array at the bottom of the heap:
//	HeapSort(a, alength);
//
// printf("Array after applying heap sort:> ");
//// Apply a heap-sorted array:
//	for (int i = 0; i < alength; i++)
//	{
//		printf("%d ", a[i]);
//	}
//
//}
Test function -- sorting
//
Heap sort function (optimized) - sorts a normal array (ascending or descending) using heap type ideas
First parameter: address of the first element of the array at the bottom of the heap.
Second parameter: the number of elements in the bottom array of the heap.
//void HeapSort(int* a, int n)
//{	
//// Previously after creating the heap type using the HeapPush function.
//// Re-applied to sorting ordinary arrays, the
//// Then we can do without the heap, too.
//// Use the HeapPush function directly along the lines of building ordinary arrays into heaps:
//	
//// Adjust upward to build a heap -- time complexity -- O(N*logN)
//// Think of the array as a fully binary tree and then build the heap:
//// In AdjustUp you can set whether the adjustment is a big or small stack adjustment.
//	for (int i = 1; i < n; i++)
//// Sorting from the second element of the array (subscript 1), with the first element defaulting to the root node, the
//// Further adjustments are made after using the AdjustUp function:
//	{
//// Previously the AdjustUp adjustment function was used for heap type operations.
//// The AdjustUp adjustment function can also be used here on normal arrays.
//// It's just that heap types need to be expanded, whereas normal arrays don't.
//// Resize the normal array as a large or small heap:
//		AdjustUp(a, i);
//	}
//
//// Now the first element is equivalent to the (small heap) root node, i.e., the minimum value
//// To pick the next smallest value again, you can only look at the remaining data as a heap
//// But the parent-child relationship is all messed up, and the remaining data is not necessarily still a heap
//// It's possible to rebuild the heap again, but it's too expensive.
//
//// Another thought: ascending order (from smallest to largest) with large heaps
//// Build the array into a big heap, and after picking out the maximum value, swap the maximum value with the most trailing value
//// so that in ascending order (from smallest to largest) a value is also lined up, i.e. the largest value is placed at the end
//// Then look at the other values except the largest value as a heap and adjust downward to select the next largest value
//// Put in the penultimate position and loop through the set -- time complexity NlogN
//// (by the same token, use a small heap if it's in descending order (largest to smallest))
//
//// In descending order (from largest to smallest) using a small heap as an example:
//
//// Get the array tail element subscript first:
//	int end = n - 1;
//// Sorting using a while loop:
//	while (end > 0)
//// The subscript of the end element of the array is greater than indicating that there are at least two more elements, continue sorting:
//	{
//// Swap the minimum (the root node of the small heap) with the tail element:
//		Swap(&a[0], &a[end]);
//
//// Look at all but the smallest value as a heap and do a downward adjustment to pick the next largest value:
//		AdjustDown(a, end, 0);
//// end is the value other than the minimum (the first n-1 values of the array)
//
//// This adjusts the tailmost value, and the end-1 loop adjusts the next one:
//		end--;
//	}
//  
//}
//
//void Test2()
//{
//// Create a heap bottom array -- node values are randomized; unsorted
//	//int a[] = { 75,65,100,32,50,60 };
//	int a[] = { 2,3,5,7,4,6,8 };
//
//	// Calculate the length of the array:
//	int alength = sizeof(a) / sizeof(int);
//
// printf("Array before applying heap sort:> ");
//// Apply the array before the heap sort:
//	for (int i = 0; i < alength; i++)
//	{
//		printf("%d ", a[i]);
//	}
//	printf("\n");
//
//// Use the HeapSort function to sort the unsorted array at the bottom of the heap:
//	HeapSort(a, alength);
//
// printf("Array after applying heap sort:> ");
//// Apply a heap-sorted array:
//	for (int i = 0; i < alength; i++)
//	{
//		printf("%d ", a[i]);
//	}
//
//}
//Test function -- sorting
// Heap sort function (re-re-optimized) -- sorts ordinary arrays (ascending or descending) using only downward adjustments
//First parameter: address of the first element of the array at the bottom of the heap.
//Second parameter: the number of elements in the bottom array of the heap.
void HeapSort(int* a, int n)
{
// downward-adjusted build heap -- time complexity: O(N)
//Think of the array to be sorted as a complete binary tree.
// Adjust downward from the penultimate first parent (non-leaf node):
for (int i = (n-1-1)/2; i >= 0; i--)
//(n-1-1)/2 -- n-1 is the subscript of the last leaf, which -1 then /2 (Eq.)
//find its parent node (the penultimate parent node), adjust that parent node after i--
// Adjust the previous parent again until it adjusts down to the root node
{
AdjustDown(a, n, i); //adjust downward from position i
}
//worst-case number of executions to build the heap: T(N) = N - log(N+1)
// Thus: the time complexity of building a heap is O(N)
// Start sorting: in descending order (largest to smallest) using a small heap as an example:
// Get the array tail element subscript first:
int end = n - 1;
// Use a while loop for sorting:
while (end > 0)
//The subscript of the end element of the array is greater than indicating that there are at least two more elements, continue sorting:
{
// Swap the minimum (root node of the mini-heap) with the tail element:
Swap(&a[0], &a[end]);
// Look at all but the smallest value as a heap and adjust downward to pick the next largest value:
AdjustDown(a, end, 0);
//end is the value other than the minimum value (the first n-1 values of the array)
// This adjusts the tail-most value, and the end-1 loop adjusts the next one:
end--;
}
}
void Test3()
{
// create a heap bottom array -- node values randomized; unsorted
//int a[] = { 75,65,100,32,50,60 };
int a[] = { 2,3,5,7,4,6,8 };
// Calculate the length of the array:
int alength = sizeof(a) / sizeof(int);
printf("Array before applying heap sorting:> ");
// Apply the array before the heap sort:
for (int i = 0; i < alength; i++)
{
printf("%d ", a[i]);
}
printf("\n");
// Use the HeapSort function to sort the unsorted array at the bottom of the heap:
HeapSort(a, alength);
printf("Array after applying heap sorting:> ");
// Apply the heap-sorted array:
for (int i = 0; i < alength; i++)
{
printf("%d ", a[i]);
}
}
// Main function:
int main() 
{
//Test0();
//Test1();
//Test2();
Test3();
return 0;
}

Recommended Today

uniapp and applet set tabBar and show and hide tabBar

(1) Set the tabBar: uni.setTabberItem({}); wx.setTabberItem({}); indexnumberisWhich item of the tabBar, counting from the left, is indexed from 0.textstringnoButton text on tabiconPathstringnoImage PathselectedIconPathstringnoImage path when selectedpagePathstringnoPage absolute pathvisiblebooleannotab Whether to display uni.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) wx.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) […]