// sl-4-DHBW-inf2 // visualize binary search trees and avl binary search trees #include #include #include "suchbaum.h" #include "avlbaum.h" #include "visualbinbaum.h" using namespace std; ////////////////////////////////////////////////////////////////////////////// struct extBsTree; // Binbaum mit Zusatzinfos typedef extBsTree * extBstPtr; struct extBsTree { DataType value; // Kopie extBstPtr left, right; // "Kopie" int inordernr; // Position in sortierter Rhf bool isleft; // Flag, ob es ein linkes Kind ist }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// extBstPtr cpBsTree(const bstPtr root, const bool isleft, int & inordernr) { ////////////////////////////////////////////////////////////////////////////// // Kopiert den Baum und berechnet Abstand vom linken Rand extBstPtr cproot, cpleft; if (root==NULL) { return NULL; } else { cpleft=cpBsTree(root->left,true,inordernr); inordernr++; cproot= new extBsTree; cproot->value=root->value; cproot->left=cpleft; cproot->inordernr = inordernr; cproot->isleft=isleft; cproot->right=cpBsTree(root->right,false,inordernr); return cproot; } } /////////////////////////////////////////////////////////////////////////////// void delTree(const extBstPtr root) { /////////////////////////////////////////////////////////////////////////////// if (root!=NULL) { delTree(root->left); delTree(root->right); delete root; } } /////////////////////////////////////////////////////////////////////////////// DataType MaxExtBsTree(const extBstPtr root) { /////////////////////////////////////////////////////////////////////////////// // root mustn't be NULL if (root->right==NULL) { return root->value; } else { return MaxExtBsTree(root->right); } } /////////////////////////////////////////////////////////////////////////////// struct extBstList; // will be used as mixed list and ring list typedef extBstList * extBstLPtr; struct extBstList { // für Levelorderausgabe extBstPtr node; extBstLPtr next; }; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void removeFirst (extBstLPtr & l, extBstPtr & node) { /////////////////////////////////////////////////////////////////////////////// // l mustn't be empty extBstLPtr tbd = l; node = l->node; l = l->next; delete tbd; } /////////////////////////////////////////////////////////////////////////////// void getListOfSuccessors(const extBstLPtr oldlist, extBstLPtr & newlist) { /////////////////////////////////////////////////////////////////////////////// // recursion! at the end newlist must point to the first new item in that list // if no new item was added, newlist must be used unchanged in the next call if (oldlist!=NULL) { if (oldlist->node->left!=NULL) { newlist = new extBstList; newlist->node = oldlist->node->left; newlist->next = NULL; if (oldlist->node->right!=NULL) { newlist->next = new extBstList; newlist->next->node = oldlist->node->right; newlist->next->next = NULL; getListOfSuccessors(oldlist->next,newlist->next->next); } else { getListOfSuccessors(oldlist->next,newlist->next); } } else { if (oldlist->node->right!=NULL) { newlist = new extBstList; newlist->node = oldlist->node->right; newlist->next = NULL; getListOfSuccessors(oldlist->next,newlist->next); } else { getListOfSuccessors(oldlist->next,newlist); } } } // else { // no more elements in oldlist } /////////////////////////////////////////////////////////////////////////////// void mput(ostream& os, char bst, int times) { /////////////////////////////////////////////////////////////////////////////// for(int i=0;inode = cpBsTree(root,false,nrOfElements); extBstPtr tbd=thisLevelList->node; // zur Speicherfreigabe am Ende thisLevelList->next = NULL; while (thisLevelList!=NULL) { // es gibt noch ein Level zum Ausgeben // nächstes Level bestimmen getListOfSuccessors(thisLevelList,nextLevelList); // unter Berücksichtigung des nächsten Levels das aktuelle ausgeben lastOffset=0; nextLevelNode=nextLevelList; while (thisLevelList!=NULL) { removeFirst(thisLevelList,thisNode); if (thisNode->left!=NULL) { nextNode=nextLevelNode->node; nextLevelNode=nextLevelNode->next; mput(os,' ',4*(nextNode->inordernr-lastOffset-1)+3); mput(os,'_',1+4*(thisNode->inordernr-nextNode->inordernr-1)); } else { mput(os,' ',4*(thisNode->inordernr-lastOffset-1)); } os << '('; if (thisNode->value<10 && thisNode->value>=0) { os << ' '; } os << thisNode->value << ')'; lastOffset=thisNode->inordernr; if (thisNode->right!=NULL) { nextNode=nextLevelNode->node; nextLevelNode=nextLevelNode->next; mput(os,'_',4*(nextNode->inordernr-lastOffset-1)+1); mput(os,' ',3); lastOffset=nextNode->inordernr; } } os << endl; lastOffset=0; nextLevelNode=nextLevelList; while (nextLevelNode) { nextNode=nextLevelNode->node; nextLevelNode=nextLevelNode->next; if (nextNode) { mput(os,' ',4*(nextNode->inordernr-lastOffset-1)); if (nextNode->isleft) os << " / "; else os << " \\ "; } lastOffset=nextNode->inordernr; } os << endl; thisLevelList=nextLevelList; nextLevelList=NULL; } delTree(tbd); // Speicher der erweiterten Baumkopie freigeben return os; } /////////////////////////////////////////////////////////////////////////////// ostream& operator << (ostream& os, const avlPtr root) { /////////////////////////////////////////////////////////////////////////////// // to be used for "cout << tree;" or "cerr << tree;" bstPtr cp=avl2bst(root); os << cp; delTree(cp); cp=avlbal2bst(root); os << cp; delTree(cp); return os; }