Created
April 23, 2014 22:00
-
-
Save macroxela/11233925 to your computer and use it in GitHub Desktop.
An OpenGL application that creates visual representations of various data structures. The user can add and remove elements from the data structures and observe what happens in real time.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DATA_AM | |
#define DATA_AM | |
#include <iostream> | |
#include <stdlib.h> | |
#include <GL/glut.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include<time.h> | |
using namespace std; | |
template<class THING> | |
class Node | |
{ | |
public: | |
THING data; | |
Node *next1; | |
Node *next2; | |
Node *parent; | |
double x1, x2; | |
double y1, y2; | |
int level; | |
Node() | |
{ | |
next1 = NULL; | |
next2 = NULL; | |
parent = NULL; | |
} | |
Node(THING x) | |
{ | |
data = x; | |
next1 = NULL; | |
next2 = NULL; | |
parent = NULL; | |
x1 = -0.9; | |
y1 = 0.9; | |
x2 = -0.8; | |
y2 = 0.8; | |
} | |
void setData(THING x) | |
{ | |
data = x; | |
} | |
/* | |
Code below borrowed from | |
http://stackoverflow.com/questions/5898922/i-have-a-problem-about-opengl-glut-glutstrokecharacter-the-code-did-not-work | |
Used to display numbers on screen | |
*/ | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
void output(double x, double y, char* text) | |
{ | |
glColor3f(1,1,1); | |
glPushMatrix(); | |
glTranslatef(x, y-0.1, 0); | |
double sc = 1300.00; | |
glScalef(1/sc, 1/sc, 1/sc); | |
glLineWidth(3); | |
for( char* p = text; *p; p++) | |
{ | |
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); | |
} | |
glPopMatrix(); | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
void displayNode() | |
{ | |
//Draw Square | |
glBegin(GL_QUADS); | |
glColor3f(1,0,1); | |
glVertex2f(x1,y1); | |
glVertex2f(x2,y1); | |
glVertex2f(x2,y2); | |
glVertex2f(x1,y2); | |
glEnd(); | |
//Display Number | |
char *ch = new char(); | |
itoa(data, ch, 10); | |
output(x1, y1, ch); | |
} | |
}; | |
class SingleLinkedList | |
{ | |
public: | |
Node<int> *head; | |
SingleLinkedList(int val) | |
{ | |
head = new Node<int>(val); | |
}; | |
void insert(int val) | |
{ | |
Node<int> *n = new Node<int>(val); | |
Node<int> *current = head; | |
if(current == NULL) | |
{ | |
head = n; | |
return; | |
} | |
while(current->next1 != NULL) | |
current = current->next1; | |
n->x1 = current->x2+0.1; | |
n->x2 = n->x1+0.1; | |
n->y1 = current->y1; | |
n->y2 = current->y2; | |
current->next1 = n; | |
} | |
void remove(int val) | |
{ | |
cout<<"Remove "<<val<<endl; | |
Node<int> *current = head; | |
Node<int> *nxt = head->next1; | |
if(head->data == val)//If data is in head | |
{ | |
double x1, x2, y1, y2; | |
double Ox1, Ox2, Oy1, Oy2; | |
if(nxt != NULL)//Initialize old values | |
{ | |
Ox1 = current->x1; | |
Ox2 = current->x2; | |
Oy1 = current->y1; | |
Oy2 = current->y2; | |
} | |
while(nxt != NULL) | |
{ | |
//Store position of neighbor | |
x1 = nxt->x1; | |
x2 = nxt->x2; | |
y1 = nxt->y1; | |
y2 = nxt->y2; | |
//Update neighbor's position | |
nxt->x1 = Ox1; | |
nxt->x2 = Ox2; | |
nxt->y1 = Oy1; | |
nxt->y2 = Oy2; | |
//Update old values | |
Ox1 = x1; | |
Ox2 = x2; | |
Oy1 = y1; | |
Oy2 = y2; | |
current = nxt; | |
nxt = nxt->next1; | |
} | |
head = head->next1; | |
return; | |
} | |
//Find desired node | |
while(nxt != NULL && nxt->data != val) | |
{ | |
current = nxt; | |
nxt = nxt->next1; | |
} | |
//If data is not found | |
if(nxt == NULL || nxt->data != val) | |
{ | |
cout<<"Not Found . . .\n"; | |
return; | |
} | |
//Update positions | |
current = nxt; | |
nxt = nxt->next1; | |
while(nxt != NULL) | |
{ | |
nxt->x1 = current->x1; | |
nxt->x2 = current->x2; | |
nxt->y1 = current->y1; | |
nxt->y2 = current->y2; | |
current = nxt; | |
nxt = nxt->next1; | |
} | |
//Remove element | |
current = head; | |
nxt = head->next1; | |
while(nxt != NULL && nxt->data != val) | |
{ | |
current = nxt; | |
nxt = nxt->next1; | |
} | |
current->next1 = nxt->next1; | |
} | |
void printList() | |
{ | |
Node<int> *current = head; | |
while(current != NULL) | |
{ | |
cout<<current->data<<", "; | |
current = current->next1; | |
} | |
cout<<endl; | |
} | |
void displayNodes() | |
{ | |
Node<int> *c = head; | |
while(c != NULL) | |
{ | |
c->displayNode(); //Display node's data | |
if(c->next1 != NULL) | |
{ | |
//Displays link to child | |
glBegin(GL_LINES); | |
glColor3f(0,1,1); | |
glVertex2f(c->x2, c->y1-0.03); | |
glVertex2f(c->next1->x1, c->next1->y1-0.03); | |
glEnd(); | |
} | |
c = c->next1; | |
} | |
} | |
}; | |
class DoubleLinkedList | |
{ | |
public: | |
Node<int> *head; | |
DoubleLinkedList(int val) | |
{ | |
head = new Node<int>(val); | |
} | |
void insert(int val) | |
{ | |
Node<int> *n = new Node<int>(val); | |
Node<int> *current = head; | |
if(head == NULL) | |
{ | |
head = n; | |
return; | |
} | |
//Go to end of linked list | |
while(current->next1 != NULL) | |
current = current->next1; | |
//Attach node and store it's new position | |
n->x1 = current->x2+0.1; | |
n->x2 = n->x1+0.1; | |
n->y1 = current->y1; | |
n->y2 = current->y2; | |
current->next1 = n; | |
n->parent = current; | |
} | |
void remove(int val) | |
{ | |
cout<<"Remove "<<val<<endl; | |
Node<int> *current = head; | |
Node<int> *nxt = head->next1; | |
//Initialize values for updating position | |
double Ox1, Ox2, Oy1, Oy2; | |
double x1, x2, y1, y2; | |
if(head->data == val) //If element is head | |
{ | |
if(nxt != NULL) | |
{ | |
Ox1 = head->x1; | |
Ox2 = head->x2; | |
Oy1 = head->y1; | |
Oy2 = head->y2; | |
} | |
nxt = head; | |
while(nxt->next1 != NULL) | |
{ | |
//Store values of next node | |
x1 = nxt->next1->x1; | |
x2 = nxt->next1->x2; | |
y1 = nxt->next1->y1; | |
y2 = nxt->next1->y2; | |
//Update position values | |
nxt->next1->x1 = Ox1; | |
nxt->next1->x2 = Ox2; | |
nxt->next1->y1 = Oy1; | |
nxt->next1->y2 = Oy2; | |
//Update old values | |
Ox1 = x1; | |
Ox2 = x2; | |
Oy1 = y1; | |
Oy2 = y2; | |
nxt = nxt->next1; | |
} | |
if(head->next1 != NULL) | |
head->next1->parent = NULL; | |
head = head->next1; | |
return; | |
} | |
//Find node with given data | |
while(nxt != NULL && nxt->data != val) | |
{ | |
current = current->next1; | |
nxt = nxt->next1; | |
} | |
//If element is not found | |
if(nxt == NULL || nxt->data != val) | |
{ | |
cout<<"Not Found . . .\n"; | |
return; | |
} | |
//To delete node the positions of all the nodes | |
//after the desired node must be updated then | |
//the desired node is deleted | |
Ox1 = nxt->x1; | |
Ox2 = nxt->x2; | |
Oy1 = nxt->y1; | |
Oy2 = nxt->y2; | |
//Go through each node after finding the desired node | |
//and update positions | |
while(nxt->next1 != NULL) | |
{ | |
//Store values of next node | |
x1 = nxt->next1->x1; | |
x2 = nxt->next1->x2; | |
y1 = nxt->next1->y1; | |
y2 = nxt->next1->y2; | |
//Update position values | |
nxt->next1->x1 = Ox1; | |
nxt->next1->x2 = Ox2; | |
nxt->next1->y1 = Oy1; | |
nxt->next1->y2 = Oy2; | |
//Update old values | |
Ox1 = x1; | |
Ox2 = x2; | |
Oy1 = y1; | |
Oy2 = y2; | |
nxt = nxt->next1; | |
} | |
//Go back to desired node | |
nxt = current->next1; | |
current->next1 = nxt->next1; | |
nxt->parent = current; | |
} | |
void printList() | |
{ | |
Node<int> *current = head; | |
while(current != NULL) | |
{ | |
cout<<current->data<<", "; | |
current = current->next1; | |
} | |
cout<<endl; | |
} | |
void reversePrint() | |
{ | |
Node<int> *current = head; | |
//Traverse to end of linked list | |
while(current->next1 != NULL) | |
current = current->next1; | |
//Print list | |
while(current != NULL) | |
{ | |
cout<<current->data<<", "; | |
current = current->parent; | |
} | |
cout<<endl; | |
} | |
void displayNodes() | |
{ | |
Node<int> *c = head; | |
while(c != NULL) | |
{ | |
c->displayNode(); //Display node's data | |
cout<<endl; | |
if(c->next1 != NULL) | |
{ | |
//Display link to child | |
glBegin(GL_LINES); | |
glColor3f(0,1,1); | |
glVertex2f(c->x2, c->y1-0.03); | |
glVertex2f(c->next1->x1, c->next1->y1-0.03); | |
glEnd(); | |
//Display link to parent | |
glBegin(GL_LINES); | |
glColor3f(0,1,0); | |
glVertex2f(c->x2, c->y2+0.03); | |
glVertex2f(c->next1->x1, c->next1->y2+0.03); | |
glEnd(); | |
} | |
c = c->next1; | |
} | |
} | |
}; | |
class BinaryTree | |
{ | |
public: | |
Node<int> *root; | |
BinaryTree(int val) | |
{ | |
root = new Node<int>(val); | |
//Initialize root position | |
root->x1 = -0.05; | |
root->y1 = 0.9; | |
root->x2 = 0.05; | |
root->y2 = 0.8; | |
root->level = 1; //Used to avoid position overlap | |
} | |
void recInsert(Node<int> *n, Node<int> *current) | |
{ | |
if(root == NULL) | |
{ | |
root = n; | |
root->x1 = -0.05; | |
root->y1 = 0.9; | |
root->x2 = 0.05; | |
root->y2 = 0.8; | |
root->level = 1; | |
return; | |
} | |
double d = 0.5; //Spacing between nodes on x-axis | |
n->level++; | |
//Value is less than current node it goes to left | |
if(n->data <= current->data) | |
{ | |
//Left child is empty | |
if(current->next1 == NULL) | |
{ | |
current->next1 = n; | |
n->parent = current; | |
n->x1 = current->x1 - d/((double)current->level); | |
n->x2 = current->x2 - d/((double)current->level); | |
n->y1 = current->y1-0.2; | |
n->y2 = current->y2-0.2; | |
return; | |
} | |
recInsert(n,current->next1); | |
} | |
//Value is greater than current node | |
else if(n->data > current->data) | |
{ | |
//Right child is empty | |
if(current->next2 == NULL) | |
{ | |
current->next2 = n; | |
n->parent = current; | |
n->x1 = current->x1 + d/((double)current->level); | |
n->x2 = current->x2 + d/((double)current->level); | |
n->y1 = current->y1-0.2; | |
n->y2 = current->y2-0.2; | |
return; | |
} | |
recInsert(n,current->next2); | |
} | |
} | |
void insert(int val) | |
{ | |
Node<int> *n = new Node<int>(val); | |
n->level = 1; | |
recInsert(n,root); | |
} | |
Node<int>* rightMost(Node<int> *n) | |
{ | |
if(n == NULL) //Current node is Null | |
return NULL; | |
if(n->next2 == NULL) //If there is no right child it is rightmost node | |
{ | |
if(n->data > n->parent->data) | |
n->parent->next2 = n->next1; | |
else | |
n->parent->next1 = n->next1; | |
if(n->next1 != NULL) | |
n->next1->parent = n->parent; | |
return n; | |
} | |
return rightMost(n->next2); //If right child exists | |
} | |
void recRemove(Node<int> *n, int val) | |
{ | |
if(n == NULL) | |
return; | |
else if(val < n->data) | |
recRemove(n->next1,val); | |
else if(val > n->data) | |
recRemove(n->next2,val); | |
else | |
{ | |
//Find rightmost data in left subtree | |
Node<int> *mright = rightMost(n->next1); | |
//If no left subtree | |
if(mright == NULL) | |
{ | |
//if not root | |
if(n->parent != NULL) | |
{ | |
//Check if current node is left or right child | |
if(n->data > n->parent->data) //Right child | |
{ | |
n->parent->next2 = n->next2; | |
if(n->next2 != NULL) | |
{ | |
n->next2->parent = n->parent; | |
n->next2->x1 = n->x1; | |
n->next2->x2 = n->x2; | |
n->next2->y1 = n->y1; | |
n->next2->y2 = n->y2; | |
n->next2->level = n->level; | |
} | |
} | |
else //Left child | |
{ | |
n->parent->next1 = n->next2; | |
if(n->next2 != NULL) | |
{ | |
n->next2->parent = n->parent; | |
n->next2->x1 = n->x1; | |
n->next2->x2 = n->x2; | |
n->next2->y1 = n->y1; | |
n->next2->y2 = n->y2; | |
n->next2->level = n->level; | |
} | |
} | |
} | |
else //if root | |
{ | |
if(n->next2 != NULL) | |
{ | |
n->next2->parent = NULL; | |
n->next2->x1 = n->x1; | |
n->next2->x2 = n->x2; | |
n->next2->y1 = n->y1; | |
n->next2->y2 = n->y2; | |
n->next2->level = n->level; | |
} | |
root = root->next2; | |
} | |
} | |
//If left subtree exists | |
else | |
{ | |
mright->parent = n->parent; | |
mright->next1 = n->next1; | |
mright->next2 = n->next2; | |
mright->x1 = n->x1; | |
mright->x2 = n->x2; | |
mright->y1 = n->y1; | |
mright->y2 = n->y2; | |
mright->level = n->level; | |
if(n->next1 != NULL) | |
n->next1->parent = mright; | |
if(n->next2 != NULL) | |
n->next2->parent = mright; | |
if(n->parent == NULL) | |
root = mright; | |
else if(mright->data > n->parent->data) | |
n->parent->next2 = mright; | |
else | |
n->parent->next1 = mright; | |
} | |
} | |
} | |
void remove(int val) | |
{ | |
cout<<"Removing "<<val<<endl; | |
recRemove(root, val); | |
} | |
void recPrint(Node<int> *c) | |
{ | |
if(c == NULL) | |
return; | |
recPrint(c->next1); | |
cout<<" "<<c->data<<" \n"; | |
recPrint(c->next2); | |
cout<<" "; | |
} | |
void printHeap() | |
{ | |
cout<<"\nPrinting heap. . .\n"; | |
recPrint(root); | |
} | |
void recDisplay(Node<int> *c) | |
{ | |
c->displayNode(); | |
if(c->next1 != NULL) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((c->x1 + c->x2)/2,c->y2); | |
glVertex2f((c->next1->x1 + c->next1->x2)/2,c->next1->y1); | |
glEnd(); | |
recDisplay(c->next1); | |
} | |
if(c->next2 != NULL) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((c->x1 + c->x2)/2,c->y2); | |
glVertex2f((c->next2->x1 + c->next2->x2)/2,c->next2->y1); | |
glEnd(); | |
recDisplay(c->next2); | |
} | |
} | |
void displayHeap() | |
{ | |
recDisplay(root); | |
} | |
}; | |
class MinHeap | |
{ | |
public: | |
Node<int> *root; | |
int size; | |
int current; | |
int count; | |
//Constructor | |
MinHeap(int val, int sz) | |
{ | |
size = sz; | |
root = new Node<int>[size+1]; | |
for(int i = 0; i <= size + 1; i++) | |
root[i].data = -999; | |
root[1].data = val; | |
current = 1; | |
count = 1; | |
//Set initial position of root | |
root[1].x1 = -0.05; | |
root[1].y1 = 0.9; | |
root[1].x2 = 0.05; | |
root[1].y2 = 0.8; | |
} | |
//Print heap in command prompt | |
void printHeap() | |
{ | |
for(int i = 1; i <= count; i++) | |
{ | |
cout<<root[i].data<<" "; | |
} | |
cout<<endl; | |
} | |
//Recursive insert | |
void recInsert(int cnt) | |
{ | |
if(cnt == 1 || cnt == 0) | |
return; | |
if(cnt%2 == 1) | |
{ | |
if(root[(cnt-1)/2].data <= root[cnt].data) | |
return; | |
else if(root[(cnt-1)/2].data > root[cnt].data) | |
{ | |
int v1 = root[(cnt-1)/2].data; | |
root[(cnt-1)/2].data = root[cnt].data; | |
root[cnt].data = v1; | |
recInsert((cnt-1)/2); | |
} | |
} | |
else | |
{ | |
if(root[cnt/2].data <= root[cnt].data) | |
return; | |
else if(root[cnt/2].data > root[cnt].data) | |
{ | |
int v1 = root[cnt/2].data; | |
root[cnt/2].data = root[cnt].data; | |
root[cnt].data = v1; | |
recInsert(cnt/2); | |
} | |
} | |
} | |
//Create node with data and send to recursive insert | |
void insert(int val) | |
{ | |
double d = 0.5; //Spacing between nodes on x-axis | |
//if root is empty | |
if(root[1].data == -999) | |
{ | |
root[1].data = val; | |
count = 1; | |
return; | |
} | |
//Children of child i are 2i and 2i+1 | |
count++; | |
if(root[current*2].data == -999) | |
{ | |
//If the left child is empty i.e. even # | |
root[current*2].data = val; | |
root[current*2].x1 = root[current].x1 - 0.2/((double)current/2); | |
root[current*2].x2 = root[current].x2 - 0.2/((double)current/2); | |
root[current*2].y1 = root[current].y1 - 0.2; | |
root[current*2].y2 = root[current].y2 - 0.2; | |
recInsert(current*2); | |
} | |
else | |
{ | |
//If left child contains element but right | |
//does not i.e. odd # | |
root[current*2+1].data = val; | |
root[current*2+1].x1 = root[current].x1 + 0.2/((double)current/2); | |
root[current*2+1].x2 = root[current].x2 + 0.2/((double)current/2); | |
root[current*2+1].y1 = root[current].y1 - 0.2; | |
root[current*2+1].y2 = root[current].y2 - 0.2; | |
recInsert(current*2+1); | |
current++; | |
} | |
//printHeap(); | |
} | |
//Swap parent and child elements | |
void swap(int pos1, int pos2) | |
{ | |
int val = root[pos1].data; | |
root[pos1].data = root[pos2].data; | |
root[pos2].data = val; | |
} | |
//Rearranges heap elements to be properly ordered | |
void recFix(int pos) | |
{ | |
if(root[2*pos].data == -999) | |
return; | |
if(root[2*pos+1].data == -999) | |
{ | |
if(root[pos].data > root[2*pos].data) | |
{ | |
swap(pos,2*pos); | |
} | |
return; | |
} | |
if(root[pos].data <= root[2*pos].data && root[pos].data <= root[2*pos+1].data) | |
return; | |
else if(root[pos].data > root[2*pos].data && root[pos].data > root[2*pos+1].data) | |
{ | |
if(root[2*pos].data <= root[2*pos+1].data || root[2*pos+1].data == -999) | |
{ | |
swap(pos,2*pos); | |
recFix(2*pos); | |
} | |
else | |
{ | |
swap(pos,2*pos+1); | |
recFix(2*pos+1); | |
} | |
} | |
else if(root[pos].data <= root[2*pos].data && root[pos].data > root[2*pos+1].data) | |
{ | |
swap(pos,2*pos+1); | |
recFix(2*pos+1); | |
} | |
else if(root[pos].data > root[2*pos].data && root[pos].data <= root[2*pos+1].data) | |
{ | |
swap(pos,2*pos); | |
recFix(2*pos); | |
} | |
} | |
//Removes root | |
int pop() | |
{ | |
int num = root[1].data; | |
root[1].data = root[count].data; | |
root[count].data = -999; | |
count--; | |
if(count%2 == 1) | |
current--; | |
recFix(1); | |
return num; | |
} | |
void displayHeap() | |
{ | |
for(int i = 1; i <= count; i++) | |
{ | |
root[i].displayNode(); | |
if(root[i*2].data != -999) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((root[i].x1 + root[i].x2)/2,root[i].y2); | |
glVertex2f((root[i*2].x1 + root[i*2].x2)/2,root[i*2].y1); | |
glEnd(); | |
} | |
if(root[i*2+1].data != -999) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((root[i].x1 + root[i].x2)/2,root[i].y2); | |
glVertex2f((root[i*2+1].x1 + root[i*2+1].x2)/2,root[i*2+1].y1); | |
glEnd(); | |
} | |
} | |
} | |
}; | |
class MaxHeap | |
{ | |
public: | |
Node<int> *root; | |
int size; | |
int current; | |
int count; | |
//Constructor | |
MaxHeap(int val, int sz) | |
{ | |
size = sz; | |
root = new Node<int>[size+1]; | |
for(int i = 0; i <= size + 1; i++) | |
root[i].data = -999; | |
root[1].data = val; | |
current = 1; | |
count = 1; | |
//Set initial position of root | |
root[1].x1 = -0.05; | |
root[1].y1 = 0.9; | |
root[1].x2 = 0.05; | |
root[1].y2 = 0.8; | |
} | |
//Print heap in command prompt | |
void printHeap() | |
{ | |
for(int i = 1; i <= count; i++) | |
{ | |
cout<<root[i].data<<" "; | |
} | |
cout<<endl; | |
} | |
//Recursive insert | |
void recInsert(int cnt) | |
{ | |
if(cnt == 1 || cnt == 0) | |
return; | |
if(cnt%2 == 1) | |
{ | |
if(root[(cnt-1)/2].data >= root[cnt].data)//Fixed | |
return; | |
else if(root[(cnt-1)/2].data < root[cnt].data)//Fixed | |
{ | |
int v1 = root[(cnt-1)/2].data; | |
root[(cnt-1)/2].data = root[cnt].data; | |
root[cnt].data = v1; | |
recInsert((cnt-1)/2); | |
} | |
} | |
else | |
{ | |
if(root[cnt/2].data >= root[cnt].data)//Fixed | |
return; | |
else if(root[cnt/2].data < root[cnt].data)//Fixed | |
{ | |
int v1 = root[cnt/2].data; | |
root[cnt/2].data = root[cnt].data; | |
root[cnt].data = v1; | |
recInsert(cnt/2); | |
} | |
} | |
} | |
//Create node with data and send to recursive insert | |
void insert(int val) | |
{ | |
double d = 0.5; //Spacing between nodes on x-axis | |
//if root is empty | |
if(root[1].data == -999) | |
{ | |
root[1].data = val; | |
count = 1; | |
return; | |
} | |
//Children of child i are 2i and 2i+1 | |
count++; | |
if(root[current*2].data == -999) | |
{ | |
//If the left child is empty i.e. even # | |
root[current*2].data = val; | |
root[current*2].x1 = root[current].x1 - 0.2/((double)current/2); | |
root[current*2].x2 = root[current].x2 - 0.2/((double)current/2); | |
root[current*2].y1 = root[current].y1 - 0.2; | |
root[current*2].y2 = root[current].y2 - 0.2; | |
recInsert(current*2); | |
} | |
else | |
{ | |
//If left child contains element but right | |
//does not i.e. odd # | |
root[current*2+1].data = val; | |
root[current*2+1].x1 = root[current].x1 + 0.2/((double)current/2); | |
root[current*2+1].x2 = root[current].x2 + 0.2/((double)current/2); | |
root[current*2+1].y1 = root[current].y1 - 0.2; | |
root[current*2+1].y2 = root[current].y2 - 0.2; | |
recInsert(current*2+1); | |
current++; | |
} | |
//printHeap(); | |
} | |
//Swap parent and child elements | |
void swap(int pos1, int pos2) | |
{ | |
int val = root[pos1].data; | |
root[pos1].data = root[pos2].data; | |
root[pos2].data = val; | |
} | |
//Rearranges heap elements to be properly ordered | |
void recFix(int pos) | |
{ | |
if(root[2*pos].data == -999) | |
return; | |
if(root[2*pos+1].data == -999) | |
{ | |
if(root[pos].data < root[2*pos].data)//Fixed | |
{ | |
swap(pos,2*pos); | |
} | |
return; | |
} | |
if(root[pos].data >= root[2*pos].data && root[pos].data >= root[2*pos+1].data)//Fixed | |
return; | |
else if(root[pos].data < root[2*pos].data && root[pos].data < root[2*pos+1].data)//Fixed | |
{ | |
if(root[2*pos].data >= root[2*pos+1].data || root[2*pos+1].data == -999)//Fixed | |
{ | |
swap(pos,2*pos); | |
recFix(2*pos); | |
} | |
else | |
{ | |
swap(pos,2*pos+1); | |
recFix(2*pos+1); | |
} | |
} | |
else if(root[pos].data >= root[2*pos].data && root[pos].data < root[2*pos+1].data)//Fixed | |
{ | |
swap(pos,2*pos+1); | |
recFix(2*pos+1); | |
} | |
else if(root[pos].data < root[2*pos].data && root[pos].data >= root[2*pos+1].data)//Fixed | |
{ | |
swap(pos,2*pos); | |
recFix(2*pos); | |
} | |
} | |
//Removes root | |
int pop() | |
{ | |
int num = root[1].data; | |
root[1].data = root[count].data; | |
root[count].data = -999; | |
count--; | |
if(count%2 == 1) | |
current--; | |
recFix(1); | |
return num; | |
} | |
void displayHeap() | |
{ | |
for(int i = 1; i <= count; i++) | |
{ | |
root[i].displayNode(); | |
if(root[i*2].data != -999) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((root[i].x1 + root[i].x2)/2,root[i].y2); | |
glVertex2f((root[i*2].x1 + root[i*2].x2)/2,root[i*2].y1); | |
glEnd(); | |
} | |
if(root[i*2+1].data != -999) | |
{ | |
glBegin(GL_LINES); | |
glColor3f(1,0,0); | |
glVertex2f((root[i].x1 + root[i].x2)/2,root[i].y2); | |
glVertex2f((root[i*2+1].x1 + root[i*2+1].x2)/2,root[i*2+1].y1); | |
glEnd(); | |
} | |
} | |
} | |
}; | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Interactive Visual Data Structures | |
Author: Alex Marroquin | |
Last Edited: 23 April 2014 | |
Summary: An OpenGL application that creates | |
visual representations of linked lists, | |
binary trees, min heaps, and max heaps | |
*/ | |
#include"DataStructures.h" | |
using namespace std; | |
int datach = 0; | |
int ans = 0; | |
int initial = 0; | |
int command = 0; | |
int entry = 0; | |
SingleLinkedList *list = NULL; | |
DoubleLinkedList *list2 = NULL; | |
BinaryTree *t = NULL; | |
MinHeap *h = NULL; | |
MaxHeap *hm = NULL; | |
void mydisplay() | |
{ | |
glClear(GL_COLOR_BUFFER_BIT); | |
glColor3f(1,0,1); | |
if(datach == 1) | |
list->displayNodes(); | |
else if(datach == 2) | |
list2->displayNodes(); | |
else if(datach == 3) | |
t->displayHeap(); | |
else if(datach == 4) | |
h->displayHeap(); | |
else if(datach == 5) | |
hm->displayHeap(); | |
glFlush(); | |
} | |
void topMenu(int c) | |
{ | |
if(datach == 1) | |
{ | |
cout<<"\nThe possible commands are:\n"; | |
cout<<"1) Insert (1 #)\n"; | |
cout<<"2) Remove (2 #)\n"; | |
cout<<"3) Print Linked List (3 #)\n"; | |
cin>>command>>entry; | |
cout<<"You chose "; | |
if(command == 1) | |
{ | |
cout<<"Insert value "<<entry<<endl; | |
list->insert(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 2) | |
{ | |
cout<<"Remove value "<<entry<<endl; | |
list->remove(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 3) | |
{ | |
cout<<"Print List\n"; | |
list->printList(); | |
} | |
} | |
else if(datach == 2) | |
{ | |
cout<<"\nThe possible commands are:\n"; | |
cout<<"1) Insert (1 #)\n"; | |
cout<<"2) Remove (2 #)\n"; | |
cout<<"3) Print Linked List (3 #)\n"; | |
cout<<"4) Print Linked List reverse (4 #)\n"; | |
cin>>command>>entry; | |
cout<<"You chose "; | |
if(command == 1) | |
{ | |
cout<<"Insert value "<<entry<<endl; | |
list2->insert(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 2) | |
{ | |
cout<<"Remove value "<<entry<<endl; | |
list2->remove(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 3) | |
{ | |
cout<<"Print List"<<endl; | |
list2->printList(); | |
} | |
else if(command == 4) | |
{ | |
cout<<"Print List Reverse"<<endl; | |
list2->reversePrint(); | |
} | |
} | |
else if(datach == 3) | |
{ | |
cout<<"\nThe possible commands are:\n"; | |
cout<<"1) Insert (1 #)\n"; | |
cout<<"2) Remove (2 #)\n"; | |
cout<<"3) Print Binary Tree (3 #)\n"; | |
cin>>command>>entry; | |
cout<<"You chose "; | |
if(command == 1) | |
{ | |
cout<<"Insert value "<<entry<<endl; | |
t->insert(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 2) | |
{ | |
cout<<"Remove value "<<entry<<endl; | |
t->remove(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 3) | |
{ | |
cout<<"Print tree\n"; | |
t->printHeap(); | |
} | |
else | |
cout<<"Invalid choice, try again\n"; | |
} | |
else if(datach == 4) | |
{ | |
cout<<"\nThe possible commands are:\n"; | |
cout<<"1) Insert (1 #)\n"; | |
cout<<"2) Remove (2 #)\n"; | |
cout<<"3) Print Min Heap(3 #)\n"; | |
cin>>command>>entry; | |
cout<<"You chose "; | |
if(command == 1) | |
{ | |
cout<<"Insert value "<<entry<<endl; | |
h->insert(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 2) | |
{ | |
cout<<"Remove root "<<endl; | |
cout<<"Removed "<<h->pop()<<endl; | |
glutPostRedisplay(); | |
} | |
else if(command == 3) | |
{ | |
cout<<"Print tree "<<endl; | |
h->printHeap(); | |
} | |
} | |
else if(datach == 5) | |
{ | |
cout<<"\nThe possible commands are:\n"; | |
cout<<"1) Insert (1 #)\n"; | |
cout<<"2) Remove (2 #)\n"; | |
cout<<"3) Print Max Heap(3 #)\n"; | |
cin>>command>>entry; | |
cout<<"You chose "; | |
if(command == 1) | |
{ | |
cout<<"Insert value "<<entry<<endl; | |
hm->insert(entry); | |
glutPostRedisplay(); | |
} | |
else if(command == 2) | |
{ | |
cout<<"Remove root "<<endl; | |
cout<<"Removed "<<hm->pop()<<endl; | |
glutPostRedisplay(); | |
} | |
else if(command == 3) | |
{ | |
cout<<"Print tree "<<endl; | |
hm->printHeap(); | |
} | |
} | |
} | |
void main(int argc, char** argv) | |
{ | |
int pixels = 300; | |
cout<<"Which data structure do you wish to view?\n"; | |
cout<<"1) Singly Linked List\n"; | |
cout<<"2) Doubly Linked List\n"; | |
cout<<"3) Binary Tree\n"; | |
cout<<"4) Min Heap\n"; | |
cout<<"5) Max Heap\n"; | |
cout<<"Enter choice followed by initial value. "; | |
cin>>ans>>initial; | |
if(ans == 1) | |
{ | |
list = new SingleLinkedList(initial); | |
datach = ans; | |
} | |
else if(ans == 2) | |
{ | |
list2 = new DoubleLinkedList(initial); | |
datach = ans; | |
} | |
else if(ans == 3) | |
{ | |
t = new BinaryTree(initial); | |
datach = ans; | |
} | |
else if(ans == 4) | |
{ | |
h = new MinHeap(initial, 100); | |
datach = ans; | |
} | |
else if(ans == 5) | |
{ | |
hm = new MaxHeap(initial, 100); | |
datach = ans; | |
} | |
else | |
{ | |
list = new SingleLinkedList(initial); | |
list2 = new DoubleLinkedList(initial); | |
t = new BinaryTree(initial); | |
h = new MinHeap(initial, 100); | |
datach = 1; | |
} | |
glutInit(&argc,argv); | |
glutInitWindowSize(pixels,pixels); | |
glutCreateWindow("Data Structure"); | |
glutDisplayFunc(mydisplay); | |
glutCreateMenu(topMenu); | |
glutAddMenuEntry("Test 1",1); | |
glutAttachMenu (GLUT_RIGHT_BUTTON); | |
glutMainLoop(); | |
system("pause"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment