For part of a class assignment I must play around with this code for a max heap, and then convert that sorting order so that the smallest numbers, rather than the largest numbers are at the top. For example, all numbers under 100 are children of that node, and should be under that number 100 adhering to the shape rule of a binary tree heap.
I hope this makes sense. Also, I am only a novice programmer, so if you talk to me like a third grader, that would be okay!
Here's the code.
#include <iostream>
#include <stdio.h>
using namespace std;
int linearCongruentialNumberGenerator()
{
static unsigned long x=123456789;
return (x=69069*x+362437) & 0x7fffffff;
}
struct HeapNode
{
int value;
HeapNode * left;
HeapNode * right;
HeapNode(int a_value):value(a_value),left(0),right(0){}
void add(HeapNode * child)
{
if(child->value > value)
{
int temp = value;
value = child->value;
child->value = temp;
}
if(left == 0)
left = child;
else if(right == 0)
right = child;
else if(right->size() > left->size())
right->add(child);
else
left->add(child);
}
int size()
{
int total = 1;
if(left) total += left->size();
if(right)total += right->size();
return total;
}
HeapNode * removeTopNode()
{
HeapNode * toReturn = 0;
int temp = value;
if(left != 0 && (right == 0 || left->value >= right->value))
{
value = left->value;
left->value = temp;
toReturn = left->removeTopNode();
if(toReturn == left)
left = 0;
}
else if(right != 0 && (left == 0 || right->value >= left->value))
{
value = right->value;
right->value = temp;
toReturn = right->removeTopNode();
if(toReturn == right)
right = 0;
}
if(toReturn == 0)
toReturn = this;
return toReturn;
}
void printDepthFirst()
{
cout << value << " ";
if(left)left->printDepthFirst();
if(right)right->printDepthFirst();
}
int getDepth()
{
int d = 1;
int leftDepth = 0, rightDepth = 0;
if(left) leftDepth = left->getDepth();
if(right) rightDepth = right->getDepth();
d += (leftDepth > rightDepth)?leftDepth:rightDepth;
return d;
}
void release()
{
if(left)
{
left->release();
delete left;
left = 0;
}
if(right)
{
right->release();
delete right;
right = 0;
}
}
};
class MaxHeap_UsingBinaryTreeNodes
{
HeapNode * root;
public:
MaxHeap_UsingBinaryTreeNodes():root(0){}
~MaxHeap_UsingBinaryTreeNodes()
{
if(root)
root->release();
delete root;
}
void add(int a_value)
{
HeapNode * newNode = new HeapNode(a_value);
if(root == 0)
root = newNode;
else
root->add(newNode);
}
int removeTopNode()
{
int value = 0;
HeapNode * n = root->removeTopNode();
if(n == root)
root = 0;
value = n->value;
delete n;
return value;
}
int size()
{
if(root == 0)
return 0;
return root->size();
}
void printDepthFirst()
{
if(root != 0)
root->printDepthFirst();
}
void printTree()
{
if(root == 0)
return;
int depth = root->getDepth();
int maxElements = 1;
int inRow = 1;
for(int i = 0; i < depth; ++i)
{
maxElements += inRow;
inRow *= 2;
}
int * pyramidBuffer = new int[maxElements];
int defaultValue = 0xb44df00d;
for(int i = 0; i < maxElements; ++i)
{
pyramidBuffer[i] = defaultValue;
}
inRow = 1;
int index = 0;
bool couldHaveAValue;
int value;
HeapNode * cursor;
for(int d = 0; d < depth; ++d)
{
for(int col = 0; col < inRow; ++col)
{
cursor = root;
couldHaveAValue = true;
for(int binaryDigit = 0; couldHaveAValue && binaryDigit < d; binaryDigit++)
{
if( ((col >> (d-binaryDigit-1)) & 1) == 0)
cursor = cursor->left;
else
cursor = cursor->right;
couldHaveAValue = cursor != 0;
}
value = (couldHaveAValue)?cursor->value:defaultValue;
pyramidBuffer[index++] = value;
}
if(d+1 < depth)
inRow *= 2;
}
int NUMCHARS = 2;
int maxWidth = (NUMCHARS+1)*inRow;
inRow = 1;
int leadSpace;
int betweenValues;
index = 0;
for(int d = 0; d < depth; ++d)
{
betweenValues = (maxWidth/inRow)-NUMCHARS;
leadSpace = (betweenValues)/2;
for(int i = 0; i < leadSpace; ++i)
putchar(' ');
for(int n = 0; n < inRow; ++n)
{
if(pyramidBuffer[index] != defaultValue)
printf("%02d", pyramidBuffer[index]);
else
printf("..");
index++;
if(n+1 < inRow)
{
for(int i = 0; i < betweenValues; ++i)
putchar(' ');
}
}
putchar('\n');
inRow *= 2;
}
delete [] pyramidBuffer;
}
int getDepth()
{
if(root == 0)return 0;
return root->getDepth();
}
};
class MaxHeap_UsingArray
{
int * m_data;
int m_allocated;
int m_size;
int m_depth;
void allocateSize(int a_depth)
{
int perRow = 1;
int total = 0;
for(int i = 0; i < a_depth; ++i)
{
total += perRow;
perRow *= 2;
}
int * newData = new int[total];
if(m_data)
{
int min = (total<m_allocated)?total:m_allocated;>
for(int i = 0; i < min; ++i)
newData[i] = m_data[i];
delete [] m_data;
}
m_data = newData;
m_allocated = total;
m_depth = a_depth;
}
inline int parentOf(int a_index)
{
return (a_index - 1) / 2;
}
inline int leftChild(int a_index)
{
return (a_index * 2) + 1;
}
void bubbleUp(int a_index)
{
int cursor = a_index;
int parent = parentOf(a_index), value = m_data[a_index];
while (cursor > 0 && value > m_data[parent])
{
m_data[cursor] = m_data[parent];
cursor = parent;
parent = parentOf(cursor);
}
m_data[cursor] = value;
}
void bubbleDown(int a_index)
{
int cursor = a_index, child = leftChild(a_index);
int value = m_data[a_index];
while (child < m_size)
{
if (child < (m_size - 1) && m_data[child] < m_data[child+1])
++child;
if(value < m_data[child])
{
m_data[cursor] = m_data[child];
cursor = child;
child = leftChild(cursor);
}
else break;
}
m_data[cursor] = value;
}
public:
MaxHeap_UsingArray():m_data(0),m_allocated(0),m_size(0),m_depth(0){}
void add(int a_value)
{
if(m_size >= m_allocated)
allocateSize(m_depth+1);
m_data[m_size] = a_value;
bubbleUp(m_size++);
}
int removeTopNode()
{
int value = m_data[0];
m_data[0] = m_data[--m_size];
bubbleDown(0);
return value;
}
int getDepth()
{
return m_depth;
}
int size()
{
return m_size;
}
void printTree()
{
int inRow = 1;
for(int d = 0; d < m_depth; ++d)
{
if(d+1 < m_depth)
inRow *= 2;
}
int NUMCHARS = 2;
int maxWidth = (NUMCHARS+1)*inRow;
int leadSpace;
int betweenValues;
int index = 0;
inRow = 1;
for(int d = 0; d < m_depth; ++d)
{
betweenValues = (maxWidth/inRow)-NUMCHARS;
leadSpace = (betweenValues)/2;
for(int i = 0; i < leadSpace; ++i)
putchar(' ');
for(int n = 0; n < inRow; ++n)
{
if(index < m_size)
printf("%02d", m_data[index]);
else
printf("..");
index++;
if(n+1 < inRow)
{
for(int i = 0; i < betweenValues; ++i)
putchar(' ');
}
}
putchar('\n');
inRow *= 2;
}
}
};
#include <conio.h>
void main()
{
int num;
int numRandomValues = 31;
MaxHeap_UsingArray
heap;
for(int i = 0; i < numRandomValues; ++i)
{
num = linearCongruentialNumberGenerator() % 100;
if(heap.size() > 0)
{
printf("----------\n");
heap.printTree();
}
printf("[adding %2d] (%d of %d)\n", num, i+1, numRandomValues);
_getch();
heap.add(num);
}
printf("---------- DONE ADDING ");
while(heap.size() > 0)
{
printf("----------\n");
heap.printTree();
num = heap.removeTopNode();
printf("[removing %2d] (%d left)\n", num, heap.size()+1);
_getch();
}
cout << "done!" << endl;
}
Ignore the "end conio.h, stdio.h, and end iostream tags at the end. These are generated by this automatic text to html converter and do not belong in this program.[Edit]Fixed now[/Edit]"
I am using Microsoft visual Studio 2010 under C++ dev environment. Thanks for all of your help.