# Include "heapalgorithm. H"
# Include <algorithm>
# Include <iostream>
Using namespace STD;
// Push_heap adds a new element to the heap. The premise for calling this algorithm is that the elements between [first, last) meet the heap conditions.
// The newly added element is last.
Void push_heap (int * pfirst, int * plast );
// Pop_heap deletes an element from the heap. the precondition for calling this algorithm is that the elements between [first, last) meet the heap conditions.
// The deleted element is placed at the last-1 position. Because this is Max-heap, the deleted element is the largest element in the sequence.
Void pop_heap (int * pfirst, int * plast );
// Make_heap restructured the elements in the sequence [first, last) according to the heap nature.
Void make_heap (int * pfirst, int * plast );
// Sort the heap. The prerequisite for successful sorting by calling this function is that the elements in [pfirst, plast) conform to the heap nature.
Void sort_heap (int * pfirst, int * plast );
// Determine whether a sequence [first, last) meets the heap condition. If yes, 1 is returned; otherwise, 0 is returned.
Char is_heap (int * pfirst, int * plast );
Void test_heap_algo (int * parray, int nlength );
Void test_heap_algo_in_stl (int * parray, int nlength );
Void display_array (int * parray, int nlength );
Int main ()
{
Int array [] = {0, 1, 2, 6, 4, 3, 9, 8, 7, 5, 11 };
Int array2 [] = {0, 1, 2, 6, 4, 3, 9, 8, 7, 5, 11 };
Test_heap_algo (array, sizeof (array)/sizeof (INT ));
Test_heap_algo_in_stl (array2, sizeof (array2)/sizeof (INT ));
Return 0;
}
// Static function, used to adjust the heap according to the heap nature
Static void adjust_heap (int * pfirst, int nholeindex, int nlen, int nvalue );
// Push_heap adds a new element to the heap. The premise for calling this algorithm is that the elements between [first, last) meet the heap conditions.
// The newly added element is last.
Void push_heap (int * pfirst, int * plast)
{
Int ntopindex, nholeindex, nparentindex;
Int nvalue;
If (null = pfirst | null = plast)
{
Perror ("null pointer! /N ");
Return;
}
Ntopindex = 0;
Nholeindex = (INT) (plast-pfirst-1 );
Nparentindex = (nholeindex-1)/2;
Nvalue = * (plast-1 );
// If the value of the node to be inserted is greater than that of the parent node, continue searching
While (nholeindex> ntopindex & pfirst [nparentindex] <nvalue)
{
Pfirst [nholeindex] = pfirst [nparentindex];
Nholeindex = nparentindex;
Nparentindex = (nholeindex-1)/2;
}
Pfirst [nholeindex] = nvalue;
}
// Pop_heap deletes an element from the heap. the precondition for calling this algorithm is that the elements between [first, last) meet the heap conditions.
// The deleted element is placed at the last-1 position. Because this is Max-heap, the deleted element is the largest element in the sequence.
Void pop_heap (int * pfirst, int * plast)
{
Int nvalue;
If (null = pfirst | null = plast)
{
Perror ("null pointer! /N ");
Return;
}
Nvalue = * (plast-1 );
* (Plast-1) = * pfirst;
Adjust_heap (pfirst, 0, (INT) (plast-pfirst-1), nvalue );
}
// Make_heap restructured the elements in the sequence [first, last) according to the heap nature.
Void make_heap (int * pfirst, int * plast)
{
Int nlen, nparentindex;
If (null = pfirst | null = plast)
{
Perror ("null pointer! /N ");
Return;
}
If (1> (nlen = (INT) (plast-pfirst )))
Return;
Nparentindex = (nlen-1)/2;
While (true)
{
// Adjust the value of the parent node to a proper position
Adjust_heap (pfirst, nparentindex, nlen, pfirst [nparentindex]);
If (0 = nparentindex)
Return;
Nparentindex --;
}
}
// Sort the heap. The prerequisite for successful sorting by calling this function is that the elements in [pfirst, plast) conform to the heap nature.
Void sort_heap (int * pfirst, int * plast)
{
// Call the pop_heap function to constantly put the largest element in the current sequence at the end of the sequence
While (plast-pfirst> 1)
Pop_heap (pfirst, plast --);
}
// Determine whether a sequence [first, last) meets the heap condition. If yes, 1 is returned; otherwise, 0 is returned.
Char is_heap (int * pfirst, int * plast)
{
Int nlen, nparentindex, nchildindex;
If (null = pfirst | null = plast)
{
Perror ("null pointer! /N ");
Return 0;
}
Nlen = (INT) (plast-pfirst );
Nparentindex = 0;
For (nchildindex = 1; nchildindex <nlen; ++ nchildindex)
{
If (pfirst [nparentindex] <pfirst [nchildindex])
Return 0;
// When nchildindex is an even number, the parent node has been compared with its two subnodes.
// Increment the parent node by 1
If (nchildindex & 1) = 0)
++ Nparentindex;
}
Return 1;
}
// A static function is only called by adjust_heap to confirm jhou's conclusion
Static void push_heap (int * pfirst, int nholeindex, int ntopindex, int nvalue)
{
Int nparentindex;
Nparentindex = (nholeindex-1)/2;
While (nholeindex> ntopindex & pfirst [nparentindex] <nvalue)
{
Pfirst [nholeindex] = pfirst [nparentindex];
Nholeindex = nparentindex;
Nparentindex = (nholeindex-1)/2;
}
Pfirst [nholeindex] = nvalue;
}
// Adjust the heap. The nholeindex is an empty node index in the current heap, And the nlen is the sequence length to be adjusted.
// Nvalue is the value that needs to be inserted into the heap
Static void adjust_heap (int * pfirst, int nholeindex, int nlen, int nvalue)
{
Int ntopindex, nsecondchildindex;
Ntopindex = nholeindex;
Nsecondchildindex = 2 * ntopindex + 2;
While (nsecondchildindex <nlen)
{
If (pfirst [nsecondchildindex] <pfirst [nsecondchildindex-1])
-- Nsecondchildindex;
Pfirst [nholeindex] = pfirst [nsecondchildindex];
Nholeindex = nsecondchildindex;
Nsecondchildindex = 2 * nholeindex + 2;
}
If (nsecondchildindex = nlen)
{
Pfirst [nholeindex] = pfirst [nsecondchildindex-1];
Nholeindex = nsecondchildindex-1;
}
// The following two operations play the same role in this function, which confirms what jjhou says in p178 in <STL source code analysis>
// Pfirst [nholeindex] = nvalue;
Push_heap (pfirst, nholeindex, ntopindex, nvalue );
}
Void test_heap_algo (int * parray, int nlength)
{
STD: cout <"/ntest_heap_algo ()/n ";
Make_heap (parray, parray + nlength );
Display_array (parray, nlength );
Push_heap (parray, parray + nlength );
Display_array (parray, nlength );
Pop_heap (parray, parray + nlength );
Display_array (parray, nlength );
If (is_heap (parray, parray + nlength-1 ))
{
STD: cout <"is heap! /N ";
}
Else
{
STD: cout <"is not heap! /N ";
}
Make_heap (parray, parray + nlength );
Display_array (parray, nlength );
If (is_heap (parray, parray + nlength ))
{
STD: cout <"is heap! /N ";
}
Else
{
STD: cout <"is not heap! /N ";
}
Sort_heap (parray, parray + nlength );
Display_array (parray, nlength );
}
Void test_heap_algo_in_stl (int * parray, int nlength)
{
STD: cout <"/ntest_heap_algo_in_stl ()/n ";
STD: make_heap (parray, parray + nlength );
Display_array (parray, nlength );
STD: push_heap (parray, parray + nlength );
Display_array (parray, nlength );
STD: pop_heap (parray, parray + nlength );
Display_array (parray, nlength );
// Note that is_heap is not an algorithm supported by STL. It seems that this function is available only for SGI implementation!
If (is_heap (parray, parray + nlength-1 ))
{
STD: cout <"is heap! /N ";
}
Else
{
STD: cout <"is not heap! /N ";
}
STD: make_heap (parray, parray + nlength );
Display_array (parray, nlength );
If (is_heap (parray, parray + nlength ))
{
STD: cout <"is heap! /N ";
}
Else
{
STD: cout <"is not heap! /N ";
}
STD: sort_heap (parray, parray + nlength );
Display_array (parray, nlength );
}
Void display_array (int * parray, int nlength)
{
For (INT I = 0; I <nlength; ++ I)
STD: cout <parray [I] <"";
STD: cout <STD: Endl;
}
Article Source: http://www.diybl.com/course/3_program/c++/cppsl/2008914/142815.html