Visualisierung2
myVector.cpp
Go to the documentation of this file.
1 #include "myVector.h"
2 
3 
4 myVector::myVector(int size) {
5  root = new myElement;
6  leaf = new myElement;
7  heap = new myMaxheap(size);
8 
9  leaf->parent = root;
10 
11  root->left = leaf;
12  root->right = leaf;
13  support = 0;
14 }
15 
17  if (root != NULL && (root->left != leaf || root->right != leaf)) { deleteSubTree(root); }
18  support = 0;
19  delete leaf;
20  root = NULL;
21  leaf = NULL;
22  delete heap;
23  heap = NULL;
24 }
28 void myVector::deleteTree() { if (root != NULL) { deleteSubTree(root); } return; }
29 
34 
35  if (z->left != leaf) { deleteSubTree(z->left); }
36  if (z->right != leaf) { deleteSubTree(z->right); }
37  delete z;
38  z = NULL;
39  return;
40 }
41 
42 
43 // Search Functions -------------------------------------------------------------------
44 
45 // public search function - if there exists a myElement in the three with key=searchKey,
46 // it returns TRUE and foundNode is set to point to the found node; otherwise, it sets
47 // foundNode=NULL and returns FALSE
51 myElement* myVector::findItem(const int searchKey) {
52 
53  myElement *current; current = root;
54  if (current->key==0) { return NULL; } // empty tree; bail out
55  while (current != leaf) {
56  if (searchKey < current->key) { // left-or-right?
57  if (current->left != leaf) { current = current->left; } // try moving down-left
58  else { return NULL; } // failure; bail out
59  } else { //
60  if (searchKey > current->key) { // left-or-right?
61  if (current->right != leaf) { current = current->right; } // try moving down-left
62  else { return NULL; } // failure; bail out
63  } else { return current; } // found (searchKey==current->key)
64  }
65  }
66  return NULL;
67 }
68 
69 // Return Item Functions -------------------------------------------------------------------
70 // public function which returns the tree, via pre-order traversal, as a linked list
74 myDpair* myVector::returnTreeAsList() { // pre-order traversal
75 
76  myDpair *head, *tail;
77 
78  head = new myDpair;
79  head->x = root->key;
80  head->y = root->stored;
81  tail = head;
82 
83  if (root->left != leaf) { tail = returnSubtreeAsList(root->left, tail); }
84  if (root->right != leaf) { tail = returnSubtreeAsList(root->right, tail); }
85 
86  if (head->x==0) { return NULL; /* empty tree */} else { return head; }
87 }
92  myDpair *newnode, *tail;
93 
94  newnode = new myDpair;
95  newnode->x = z->key;
96  newnode->y = z->stored;
97  head->next = newnode;
98  tail = newnode;
99 
100  if (z->left != leaf) { tail = returnSubtreeAsList(z->left, tail); }
101  if (z->right != leaf) { tail = returnSubtreeAsList(z->right, tail); }
102 
103  return tail;
104 }
109 
114  mytuple themax;
115  myElement *current;
116  current = root;
117  while (current->right != leaf) { // search to bottom-right corner of tree
118  current = current->right; } //
119  themax.m = current->stored; // store the data found
120  themax.i = current->key; //
121  themax.j = current->key; //
122 
123  return themax; // return that data
124 }
125 
126 // private functions for deleteItem() (although these could easily be made public, I suppose)
131  myElement *current;
132 
133  current = z;
134  while (current->left != leaf) { // search to bottom-right corner of tree
135  current = current->left; } //
136  return current; // return pointer to the minimum
137 }
142  myElement *current, *w;
143 
144  w = z;
145  if (w->right != leaf) { // if right-subtree exists, return min of it
146  return returnMinKey(w->right); }
147  current = w->parent; // else search up in tree
148  while ((current!=NULL) && (w==current->right)) {
149  w = current;
150  current = current->parent; // move up in tree until find a non-right-child
151  }
152  return current;
153 }
166 
167 // Heapification Functions -------------------------------------------------------------------
168 
169 // Insert Functions -------------------------------------------------------------------
170 // public insert function
174 void myVector::insertItem(int newKey, double newStored) {
175 
176  // first we check to see if newKey is already present in the tree; if so, we simply
177  // set .stored += newStored; if not, we must find where to insert the key
178  myElement *newNode, *current;
179 
180  current = findItem(newKey); // find newKey in tree; return pointer to it O(log k)
181  if (current != NULL) {
182  current->stored += newStored; // update its stored value
183  heap->updateItem(current->heap_ptr, current->stored);
184  // update corresponding myElement in heap + reheapify; O(log k)
185  } else { // didn't find it, so need to create it
186  mytuple newitem; //
187  newitem.m = newStored; //
188  newitem.i = -1; //
189  newitem.j = newKey; //
190 
191  newNode = new myElement; // myElement for the myVector
192  newNode->key = newKey; // store newKey
193  newNode->stored = newStored; // store newStored
194  newNode->color = true; // new nodes are always RED
195  newNode->parent = NULL; // new node initially has no parent
196  newNode->left = leaf; // left leaf
197  newNode->right = leaf; // right leaf
198  newNode->heap_ptr = heap->insertItem(newitem); // add new item to the myVector heap
199  support++; // increment node count in myVector
200 
201  // must now search for where to insert newNode, i.e., find the correct parent and
202  // set the parent and child to point to each other properly
203  current = root;
204  if (current->key==0) { // insert as root
205  delete root; // delete old root
206  root = newNode; // set root to newNode
207  leaf->parent = newNode; // set leaf's parent
208  current = leaf; // skip next loop
209  }
210 
211  while (current != leaf) { // search for insertion point
212  if (newKey < current->key) { // left-or-right?
213  if (current->left != leaf) { current = current->left; } // try moving down-left
214  else { // else found new parent
215  newNode->parent = current; // set parent
216  current->left = newNode; // set child
217  current = leaf; // exit search
218  }
219  } else { //
220  if (current->right != leaf) { current = current->right; } // try moving down-right
221  else { // else found new parent
222  newNode->parent = current; // set parent
223  current->right = newNode; // set child
224  current = leaf; // exit search
225  }
226  }
227  }
228 
229  // now do the house-keeping necessary to preserve the red-black properties
230  insertCleanup(newNode); // do house-keeping to maintain balance
231  }
232  return;
233 }
234 
235 // private house-keeping function for insertion
240 
241  if (z->parent==NULL) { // fix now if z is root
242  z->color = false; return; }
243  myElement *temp;
244  while (z->parent!=NULL && z->parent->color) { // while z is not root and z's parent is RED
245  if (z->parent == z->parent->parent->left) { // z's parent is LEFT-CHILD
246  temp = z->parent->parent->right; // grab z's uncle
247  if (temp->color) {
248  z->parent->color = false; // color z's parent BLACK (Case 1)
249  temp->color = false; // color z's uncle BLACK (Case 1)
250  z->parent->parent->color = true; // color z's grandparent RED (Case 1)
251  z = z->parent->parent; // set z = z's grandparent (Case 1)
252  } else {
253  if (z == z->parent->right) { // z is RIGHT-CHILD
254  z = z->parent; // set z = z's parent (Case 2)
255  rotateLeft(z); // perform left-rotation (Case 2)
256  }
257  z->parent->color = false; // color z's parent BLACK (Case 3)
258  z->parent->parent->color = true; // color z's grandparent RED (Case 3)
259  rotateRight(z->parent->parent); // perform right-rotation (Case 3)
260  }
261  } else { // z's parent is RIGHT-CHILD
262  temp = z->parent->parent->left; // grab z's uncle
263  if (temp->color) {
264  z->parent->color = false; // color z's parent BLACK (Case 1)
265  temp->color = false; // color z's uncle BLACK (Case 1)
266  z->parent->parent->color = true; // color z's grandparent RED (Case 1)
267  z = z->parent->parent; // set z = z's grandparent (Case 1)
268  } else {
269  if (z == z->parent->left) { // z is LEFT-CHILD
270  z = z->parent; // set z = z's parent (Case 2)
271  rotateRight(z); // perform right-rotation (Case 2)
272  }
273  z->parent->color = false; // color z's parent BLACK (Case 3)
274  z->parent->parent->color = true; // color z's grandparent RED (Case 3)
275  rotateLeft(z->parent->parent); // perform left-rotation (Case 3)
276  }
277  }
278  }
279 
280  root->color = false; // color the root BLACK
281  return;
282 }
283 
284 // Delete Functions -------------------------------------------------------------------
285 // public delete function
289 void myVector::deleteItem(int killKey) {
290  myElement *x, *y, *z;
291 
292 
293  z = findItem(killKey);
294  if (z == NULL) { return; } // item not present; bail out
295 
296  if (z != NULL) {
297  mytuple newmax = heap->returnMaximum(); // get old maximum in O(1)
298  heap->deleteItem(z->heap_ptr); // delete item in the max-heap O(log k)
299  }
300 
301  if (support==1) { // -- attempt to delete the root
302  root->key = 0; // restore root node to default state
303  root->stored = -4294967296.0; //
304  root->color = false; //
305  root->parent = NULL; //
306  root->left = leaf; //
307  root->right = leaf; //
308  root->heap_ptr = NULL; //
309  support--; // set support to zero
310  return; // exit - no more work to do
311  }
312 
313  if (z != NULL) {
314  support--; // decrement node count
315  if ((z->left == leaf) || (z->right==leaf)) { // case of less than two children
316  y = z; } // set y to be z
317  else { y = returnSuccessor(z); } // set y to be z's key-successor
318 
319  if (y->left!=leaf) { x = y->left; } // pick y's one child (left-child)
320  else { x = y->right; } // (right-child)
321  x->parent = y->parent; // make y's child's parent be y's parent
322 
323  if (y->parent==NULL) { root = x; } // if y is the root, x is now root
324  else { //
325  if (y == y->parent->left) { // decide y's relationship with y's parent
326  y->parent->left = x; // replace x as y's parent's left child
327  } else { //
328  y->parent->right = x; } // replace x as y's parent's left child
329  } //
330 
331  if (y!=z) { // insert y into z's spot
332  z->key = y->key; // copy y data into z
333  z->stored = y->stored; //
334  z->heap_ptr = y->heap_ptr; //
335  } //
336 
337  if (y->color==false) { deleteCleanup(x); } // do house-keeping to maintain balance
338  delete y; // deallocate y
339  y = NULL; // point y to NULL for safety
340  } //
341 
342  return;
343 }
348  myElement *w, *t;
349  while ((x != root) && (x->color==false)) { // until x is the root, or x is RED
350  if (x==x->parent->left) { // branch on x being a LEFT-CHILD
351  w = x->parent->right; // grab x's sibling
352  if (w->color==true) { // if x's sibling is RED
353  w->color = false; // color w BLACK (case 1)
354  x->parent->color = true; // color x's parent RED (case 1)
355  rotateLeft(x->parent); // left rotation on x's parent (case 1)
356  w = x->parent->right; // make w be x's right sibling (case 1)
357  }
358  if ((w->left->color==false) && (w->right->color==false)) {
359  w->color = true; // color w RED (case 2)
360  x = x->parent; // examine x's parent (case 2)
361  } else { //
362  if (w->right->color==false) { //
363  w->left->color = false; // color w's left child BLACK (case 3)
364  w->color = true; // color w RED (case 3)
365  t = x->parent; // store x's parent
366  rotateRight(w); // right rotation on w (case 3)
367  x->parent = t; // restore x's parent
368  w = x->parent->right; // make w be x's right sibling (case 3)
369  } //
370  w->color = x->parent->color; // make w's color = x's parent's (case 4)
371  x->parent->color = false; // color x's parent BLACK (case 4)
372  w->right->color = false; // color w's right child BLACK (case 4)
373  rotateLeft(x->parent); // left rotation on x's parent (case 4)
374  x = root; // finished work. bail out (case 4)
375  } //
376  } else { // x is RIGHT-CHILD
377  w = x->parent->left; // grab x's sibling
378  if (w->color==true) { // if x's sibling is RED
379  w->color = false; // color w BLACK (case 1)
380  x->parent->color = true; // color x's parent RED (case 1)
381  rotateRight(x->parent); // right rotation on x's parent (case 1)
382  w = x->parent->left; // make w be x's left sibling (case 1)
383  }
384  if ((w->right->color==false) && (w->left->color==false)) {
385  w->color = true; // color w RED (case 2)
386  x= x->parent; // examine x's parent (case 2)
387  } else { //
388  if (w->left->color==false) { //
389  w->right->color = false; // color w's right child BLACK (case 3)
390  w->color = true; // color w RED (case 3)
391  t = x->parent; // store x's parent
392  rotateLeft(w); // left rotation on w (case 3)
393  x->parent = t; // restore x's parent
394  w = x->parent->left; // make w be x's left sibling (case 3)
395  } //
396  w->color = x->parent->color; // make w's color = x's parent's (case 4)
397  x->parent->color = false; // color x's parent BLACK (case 4)
398  w->left->color = false; // color w's left child BLACK (case 4)
399  rotateRight(x->parent); // right rotation on x's parent (case 4)
400  x = root; // x is now the root (case 4)
401  }
402  }
403  }
404  x->color = false; // color x (the root) BLACK (exit)
405 
406  return;
407 }
408 
409 // Rotation Functions -------------------------------------------------------------------
414  myElement *y;
415  // do pointer-swapping operations for left-rotation
416  y = x->right; // grab right child
417  x->right = y->left; // make x's RIGHT-CHILD be y's LEFT-CHILD
418  y->left->parent = x; // make x be y's LEFT-CHILD's parent
419  y->parent = x->parent; // make y's new parent be x's old parent
420 
421  if (x->parent==NULL) { root = y; } // if x was root, make y root
422  else { //
423  if (x == x->parent->left) // if x is LEFT-CHILD, make y be x's parent's
424  { x->parent->left = y; } // left-child
425  else { x->parent->right = y; } // right-child
426  } //
427  y->left = x; // make x be y's LEFT-CHILD
428  x->parent = y; // make y be x's parent
429 
430  return;
431 }
436  myElement *x;
437  // do pointer-swapping operations for right-rotation
438  x = y->left; // grab left child
439  y->left = x->right; // replace left child yith x's right subtree
440  x->right->parent = y; // replace y as x's right subtree's parent
441 
442  x->parent = y->parent; // make x's new parent be y's old parent
443  if (y->parent==NULL) { root = x; } // if y was root, make x root
444  else {
445  if (y == y->parent->right) // if y is RIGHT-CHILD, make x be y's parent's
446  { y->parent->right = x; } // right-child
447  else { y->parent->left = x; } // left-child
448  }
449  x->right = y; // make y be x's RIGHT-CHILD
450  y->parent = x; // make x be y's parent
451 
452  return;
453 }
454 
455 // Display Function -------------------------------------------------------------------
456 // public
461  mytuple max = heap->returnMaximum();
462  std::cout << "\nTREE SIZE = " << support << std::endl;
463  std::cout << "HEAP SIZE = " << heap->heapSize() << std::endl;
464  std::cout << "MAXIMUM (" << max.j<< " " << max.m << ")" << std::endl;
465  std::cout << "# "; printSubTree(root);
466  return;
467 }
468 
469 void myVector::printHeap() { heap->printHeap(); return; }
470 
471 //private
476  if (z==leaf) { return; }
477  else {
478  std::cout << "(" << z->key << " " << z->stored << " " << z->color << ") [" << z->heap_ptr << "]"<<std::endl;
479  std::cout << "L "; printSubTree(z->left); std::cout << std::endl;
480  std::cout << "R "; printSubTree(z->right); std::cout << std::endl;
481  }
482  return;
483 }
484 // ------------------------------------------------------------------------------------
485 
myElement * parent
Pointer zum Elternknoten.
Definition: myElement.h:26
myElement * leaf
Liste aller Blaetter im Baum.
Definition: myVector.h:28
void rotateRight(myElement *y)
Routiert den Baum am Element x um 1 nach rechts.
Definition: myVector.cpp:435
void insertItem(int newKey, double newStored)
Fuegt den angegeben Wert an der Stelle des angegeben Keys in den Baum ein.
Definition: myVector.cpp:174
void updateItem(mytuple *address, mytuple newData)
Updated das Element an der angegeben Adresse mit dem uebergeben Wert.
Definition: myMaxheap.cpp:214
void printHeap()
Gibt die Elemente im Heap aus.
Definition: myMaxheap.cpp:275
mytuple returnMaximum()
Gibt das maximale Element im Heap zurueck. Keine Aenderungen im Heap.
Definition: myMaxheap.cpp:56
int returnArraysize()
Gibt die Groesse des Wertearrays zurueck.
Definition: myMaxheap.cpp:67
bool color
Farbmarkierung des Knotens im Baum (true = rot, false = schwarz).
Definition: myElement.h:24
myElement * root
Wurzelknoten des Baumes.
Definition: myVector.h:27
myDpair * returnSubtreeAsList(myElement *z, myDpair *head)
Gibt den Unterbaum von z als Liste von Dpairs zurueck.
Definition: myVector.cpp:91
void rotateLeft(myElement *x)
Routiert den Baum am Element x um 1 nach links.
Definition: myVector.cpp:413
myElement * returnSuccessor(myElement *z)
Gibt den Nachfolger von Element z zurueck.
Definition: myVector.cpp:141
void printSubTree(myElement *z)
Gibt den Unterbaum von aus.
Definition: myVector.cpp:475
mytuple * heap_ptr
Pointer zur Position des Elements im myMaxheap.
Definition: myElement.h:22
myVector(int size)
Definition: myVector.cpp:4
void insertCleanup(myElement *z)
Ordnet den Baum nach einfuegen eines Elementes wieder.
Definition: myVector.cpp:239
myDpair * next
Pointer auf naechstes Datenpaar.
Definition: myDpair.h:9
int returnHeaplimit()
Gibt die Groesse des Heaps aus (1-maxsize).
Definition: myVector.cpp:165
void printHeap()
Gibt die Elemente des Heaps aus.
Definition: myVector.cpp:469
myElement * right
Pointer zum rechten Kind.
Definition: myElement.h:28
void deleteTree()
Loescht alle Elemente aus den Baum.
Definition: myVector.cpp:28
myElement * left
Pointer zum linken Kind.
Definition: myElement.h:27
int heapSize()
gibt die Groesse des heaps zurueck (maxheap-1).
Definition: myMaxheap.cpp:269
int returnNodecount()
Liefert die Anzahl der Elemente im Baum zurueck.
Definition: myVector.cpp:157
myDpair * returnTreeAsList()
Liefert den gesamten Baum als eine Liste von DPairs zurueck.
Definition: myVector.cpp:74
int returnHeaplimit()
Gibt den Index vom ersten ungenutzen Element zurueck.
Definition: myMaxheap.cpp:71
double y
Beschreibt den Wert/Parameter an der Stelle x.
Definition: myDpair.h:8
int key
Der Key der Position im Baum.
Definition: myElement.h:20
mytuple returnMaxStored()
Liefert die Adresse und den Wert des maximalen Elements im Baum zurueck.
Definition: myVector.cpp:108
mytuple * insertItem(const mytuple newData)
Fuegt newData in den Heap ein und gibt die Adresse davon zurueck.
Definition: myMaxheap.cpp:193
void printTree()
Gibt den Baum in "in Order" Reihenfolge aus.
Definition: myVector.cpp:460
Definition: myDpair.h:4
~myVector(void)
Definition: myVector.cpp:16
myElement * returnMinKey(myElement *z)
Gibt das kleinste Element im Unterbaum von z zurueck.
Definition: myVector.cpp:130
void deleteItem(mytuple *address)
Entfernt das Element an der angegeben Adresse.
Definition: myMaxheap.cpp:235
mytuple returnMaxKey()
Liefert die Adresse des maximalen Elements im Baum zurueck.
Definition: myVector.cpp:113
int i
Zeilenindex des Elements.
Definition: myElement.h:9
myElement * findItem(const int searchKey)
Sucht das Element an den angegeben Key und gibt es zurueck.
Definition: myVector.cpp:51
int returnArraysize()
Gibt die Maxsize des Heaps aus.
Definition: myVector.cpp:161
int support
Anzahl der Elemente im Baum.
Definition: myVector.h:30
double m
Abgelegter Wert/Parameter.
Definition: myElement.h:8
void deleteSubTree(myElement *z)
Loesche den Unterbaum von z.
Definition: myVector.cpp:33
myMaxheap * heap
Maxheap des Baumes.
Definition: myVector.h:29
void deleteCleanup(myElement *x)
Ordnet den Baum nach loeschen eines Elementes wieder.
Definition: myVector.cpp:347
int x
Beschreibt einen Key oder einen Index.
Definition: myDpair.h:7
int j
Spaltenindex des Elements.
Definition: myElement.h:10
void deleteItem(int killKey)
Entfernt das Element an den angegeben Key aus den Baum.
Definition: myVector.cpp:289
double stored
Der Wert/Parameter an dieser Stelle.
Definition: myElement.h:21