diff --git a/Uebung 6/Uebung6_2/ExtendedBinaryTree.cpp b/Uebung 6/Uebung6_2/ExtendedBinaryTree.cpp new file mode 100644 index 0000000..d0fa92a --- /dev/null +++ b/Uebung 6/Uebung6_2/ExtendedBinaryTree.cpp @@ -0,0 +1,164 @@ +#include "ExtendedBinaryTree.h" +#include + +ExtendedBinaryTree::ExtendedBinaryTree(Ware *rootNodeKey, int priority) { + ExtendedBinaryTreeNode *root = + new ExtendedBinaryTreeNode(rootNodeKey, priority); + this->rootNode = root; +} + +ExtendedBinaryTreeNode *ExtendedBinaryTree::insert(Ware *key, int priority) { + return this->rootNode->insert(key, priority); +} + +ExtendedBinaryTreeNode *ExtendedBinaryTree::search(int value) { + ExtendedBinaryTreeNode *node = this->rootNode; + while (value != node->key->getVerkaufspreis() && node != nullptr) { + if (value > node->key->getVerkaufspreis()) { + node = node->right; + } else { + node = node->left; + } + } + return node; +} + +ExtendedBinaryTreeNode *ExtendedBinaryTree::deleteItem(Ware *key) { + return this->rootNode->deleteItem(key); +} + +ExtendedBinaryTreeNode * +ExtendedBinaryTree::findMin(ExtendedBinaryTreeNode *node) { + while (node->left != nullptr) { + node = node->left; + } + return node; +} + +ExtendedBinaryTreeNode * +ExtendedBinaryTree::findMax(ExtendedBinaryTreeNode *node) { + while (node->right != nullptr) { + node = node->right; + } + return node; +} + +// function to print a tree in pre-order: (sub)root, left (sub)tree, right +// (sub)tree +std::string ExtendedBinaryTree::printPreorder(ExtendedBinaryTreeNode *node) { + std::stringstream output; + output << *(node->key) << " " << node->priority << std::endl; + + if (node->left != nullptr) { + output << this->printPreorder(node->left); + } + if (node->right != nullptr) { + output << this->printPreorder(node->right); + } + return output.str(); +} + +std::string ExtendedBinaryTree::printPreorder() { + return this->printPreorder(this->rootNode); +} + +std::string ExtendedBinaryTree::printPostorder() { + return this->printPostorder(this->rootNode); +} + +std::string ExtendedBinaryTree::printPostorder(ExtendedBinaryTreeNode *node) { + std::stringstream output; + + if (node->left != nullptr) { + output << this->printPreorder(node->left); + } + if (node->right != nullptr) { + output << this->printPreorder(node->right); + } + output << *(node->key) << std::endl; + return output.str(); +} + +std::string ExtendedBinaryTree::printInorder() { + return this->printInorder(this->rootNode); +} + +std::string ExtendedBinaryTree::printInorder(ExtendedBinaryTreeNode *node) { + std::stringstream output; + + if (node->left != nullptr) { + output << this->printPreorder(node->left); + } + output << *(node->key) << std::endl; + + if (node->right != nullptr) { + output << this->printPreorder(node->right); + } + return output.str(); +} + +std::string ExtendedBinaryTree::printPriority() { + return this->printPriority(this->rootNode, INT_MAX); +} + +std::string ExtendedBinaryTree::printPriority(ExtendedBinaryTreeNode *node, + int max) { + std::stringstream output; + + // Print the node + if (node->priority < max) { + output << *(node->key) << " Priority: " << node->priority << std::endl; + } + + // find out which of the children has lower priority + ExtendedBinaryTreeNode *bigger = nullptr; + ExtendedBinaryTreeNode *smaller = nullptr; + + if (node->left != nullptr) { + if (node->right != nullptr) { + smaller = node->left->priority < node->right->priority ? node->left + : node->right; + bigger = node->left->priority > node->right->priority ? node->left + : node->right; + } else { + smaller = node->left; + } + } else if (node->right != nullptr) { + smaller = node->right; + } + + if (smaller != nullptr) { + int prio; + if (bigger != nullptr) { + if (bigger->priority < max) { + + prio = bigger->priority; + } else { + prio = max; + } + } else { + prio = INT_MAX; + } + output << printPriority(smaller, prio); + } + if (bigger != nullptr) { + output << printPriority(bigger, INT_MAX); + } + return output.str(); +} +std::string ExtendedBinaryTree::printPriorityBruteForce() { + // return ExtendedBinaryTree::printPriorityBruteForce(this->rootNode, + // INT_MAX); + int maxprinted = 0; + ExtendedBinaryTreeNode *maxprintedNode = nullptr; + while (true) { + } +} + +std::string +ExtendedBinaryTree::printPriorityBruteForce(ExtendedBinaryTreeNode *key, + int max) { + int currentMin = max; + while (true) { + } +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/ExtendedBinaryTree.h b/Uebung 6/Uebung6_2/ExtendedBinaryTree.h new file mode 100644 index 0000000..d2de798 --- /dev/null +++ b/Uebung 6/Uebung6_2/ExtendedBinaryTree.h @@ -0,0 +1,33 @@ +#include "ExtendedBinaryTreeNode.h" +#include +#include + +#pragma once + +class ExtendedBinaryTree { +public: + ExtendedBinaryTreeNode *rootNode; + + ExtendedBinaryTree(Ware *rootNodeKey, int priority); + + ExtendedBinaryTreeNode *search(int value); + ExtendedBinaryTreeNode *insert(Ware *key, int priority); + ExtendedBinaryTreeNode *deleteItem(Ware *key); + ExtendedBinaryTreeNode *findMin(ExtendedBinaryTreeNode *node); + ExtendedBinaryTreeNode *findMax(ExtendedBinaryTreeNode *node); + std::string printPreorder(ExtendedBinaryTreeNode *node); + std::string printPreorder(); + std::string printPostorder(ExtendedBinaryTreeNode *node); + std::string printPostorder(); + std::string printInorder(ExtendedBinaryTreeNode *node); + std::string printInorder(); + std::string printPriority(); + std::string printPriority(ExtendedBinaryTreeNode *node, int max); + std::string printPriorityBruteForce(); + std::string printPriorityBruteForce(ExtendedBinaryTreeNode *node, int max); +}; + +// std::string printPreorder(BinaryTreeNode* node); +// /* -- Your TODO -- */ +// std::string printPostorder(BinaryTreeNode* node); +// std::string printInorder(BinaryTreeNode* node); \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.cpp b/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.cpp new file mode 100644 index 0000000..496be84 --- /dev/null +++ b/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.cpp @@ -0,0 +1,86 @@ +#include "ExtendedBinaryTreeNode.h" + +#include + +ExtendedBinaryTreeNode::ExtendedBinaryTreeNode(Ware *key, int priority) { + this->key = key; + this->left = nullptr; + this->right = nullptr; + this->priority = priority; +} + +ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::insert(Ware *key, + int priority) { + if (key->getVerkaufspreis() > this->key->getVerkaufspreis()) { + if (this->right == nullptr) { + ExtendedBinaryTreeNode *temp = new ExtendedBinaryTreeNode(key, priority); + this->right = temp; + return this->right; + } + this->right->insert(key, priority); + } else { + if (this->left == nullptr) { + ExtendedBinaryTreeNode *temp = new ExtendedBinaryTreeNode(key, priority); + this->left = temp; + return this->left; + } + this->left->insert(key, priority); + } + return this; +} + +ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::deleteItem(Ware *key) { + ExtendedBinaryTreeNode *node = this; + + if (node == nullptr) { + return this; + } else if (key->getVerkaufspreis() < node->key->getVerkaufspreis()) { + node->left = node->left->deleteItem(key); + } else if (key->getVerkaufspreis() > node->key->getVerkaufspreis()) { + node->right = node->right->deleteItem(key); + } else { + if (node->left == nullptr && node->right == nullptr) { + delete node; + node = nullptr; + } else if (node->left == nullptr) { // only children in right subtree + ExtendedBinaryTreeNode *temp = node; + node = node->right; + delete temp; + } else if (this->right == nullptr) { // only children in left subtree + ExtendedBinaryTreeNode *temp = node; + node = node->left; + delete temp; + } else { // we have to keep the BST structure, here, we look for the minimum + // in the right subtree (see lecture) + ExtendedBinaryTreeNode *temp = node->right; + while (temp->left != nullptr) { + temp = temp->left; + } + node->key = temp->key; + node->right = node->right->deleteItem(temp->key); + } + } + return node; +} + +ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::leftRotation() { + // std::cout << "Do a left rotation on node " << this->key << "\n"; + ExtendedBinaryTreeNode *rightNode = this->right; + ExtendedBinaryTreeNode *leftOfRightNode = rightNode->left; + + rightNode->left = this; + this->right = leftOfRightNode; + return rightNode; +} + +// perform a right rotation (see lecture) +ExtendedBinaryTreeNode *ExtendedBinaryTreeNode::rightRotation() { + // std::cout << "Do a right rotation on node " << this->key << "\n"; + ExtendedBinaryTreeNode *leftNode = this->left; + ExtendedBinaryTreeNode *rightOfLeftNode = leftNode->right; + + leftNode->right = this; + this->left = rightOfLeftNode; + + return leftNode; +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.h b/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.h new file mode 100644 index 0000000..7261bbb --- /dev/null +++ b/Uebung 6/Uebung6_2/ExtendedBinaryTreeNode.h @@ -0,0 +1,17 @@ +#pragma once +#include "Ware.h" + +class ExtendedBinaryTreeNode { +public: + Ware *key; + int priority; + ExtendedBinaryTreeNode *left; + ExtendedBinaryTreeNode *right; + + ExtendedBinaryTreeNode(Ware *key, int priority); + + ExtendedBinaryTreeNode *insert(Ware *key, int priority); + ExtendedBinaryTreeNode *deleteItem(Ware *key); + ExtendedBinaryTreeNode *leftRotation(); + ExtendedBinaryTreeNode *rightRotation(); +}; \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/Makefile b/Uebung 6/Uebung6_2/Makefile new file mode 100644 index 0000000..3eca13e --- /dev/null +++ b/Uebung 6/Uebung6_2/Makefile @@ -0,0 +1,51 @@ + +# Name of the binary for Development +BINARY = main +# Name of the binary for Release +FINAL = prototyp +# Object files +OBJS = Ware.o ExtendedBinaryTreeNode.o ExtendedBinaryTree.o main.o +# Compiler flags +CFLAGS = -Werror -Wall -std=c++17 -g -fsanitize=address,undefined +# Linker flags +LFLAGS = -fsanitize=address,undefined +#Which Compiler to use +COMPILER = c++ + + +# all target: builds all important targets +all: binary + +final : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${FINAL} ${OBJS} + +binary : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS} + +# Links the binary +${BINARY} : ${OBJS} + ${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS} + + +# Compiles a source-file (any file with file extension .c) into an object-file +# +# "%" is a wildcard which matches every file-name (similar to * in regular expressions) +# Such a rule is called a pattern rule (because it matches a pattern, see https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html), +# which are a form of so called implicit rules (see https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html) +# "$@" and "$<" are so called automatic variables (see https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html) +%.o : %.cpp + ${COMPILER} -c ${CFLAGS} -o $@ $< + + +# Rules can not only be used for compiling a program but also for executing a program +run: ${BINARY} + ./${BINARY} + + +# Delete all build artifacts +clean : + rm -rf ${BINARY} ${OBJS} + + +# all and clean are a "phony" targets, meaning they are no files +.PHONY : all clean diff --git a/Uebung 6/Uebung6_2/Ware.cpp b/Uebung 6/Uebung6_2/Ware.cpp new file mode 100644 index 0000000..5bfd735 --- /dev/null +++ b/Uebung 6/Uebung6_2/Ware.cpp @@ -0,0 +1,9 @@ +#include "Ware.h" + +std::ostream &operator<<(std::ostream &out, const Ware &ware) { + out << "Name: " << ware.getBezeichnung() << ", SN: " << ware.getSeriennummer() + << ", Gewicht: " << ware.getGewicht() + << ", EK: " << ware.getEinkaufspreis() + << ", VK: " << ware.getVerkaufspreis(); + return out; +} \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/Ware.h b/Uebung 6/Uebung6_2/Ware.h new file mode 100644 index 0000000..b072d56 --- /dev/null +++ b/Uebung 6/Uebung6_2/Ware.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include + +class Ware { +private: + std::string bezeichnung; + int seriennummer; + double gewicht; + double einkaufspreis; + double verkaufspreis; + +public: + std::string getBezeichnung() const { return this->bezeichnung; } + + void setBezeichnung(std::string bezeichnung) { + this->bezeichnung = bezeichnung; + } + + int getSeriennummer() const { return this->seriennummer; } + + void setSeriennummer(int seriennummer) { this->seriennummer = seriennummer; } + + double getGewicht() const { return this->gewicht; } + + void setGewicht(double gewicht) { this->gewicht = gewicht; } + + double getEinkaufspreis() const { return this->einkaufspreis; } + + void setEinkaufspreis(double einkaufspreis) { + this->einkaufspreis = einkaufspreis; + } + + double getVerkaufspreis() const { return this->verkaufspreis; } + + void setVerkaufspreis(double verkaufspreis) { + this->verkaufspreis = verkaufspreis; + } + + Ware(std::string bezeichnung, int seriennummer, double gewicht, + double einkaufspreis, double verkaufspreis) + : bezeichnung(bezeichnung), seriennummer(seriennummer), gewicht(gewicht), + einkaufspreis(einkaufspreis), verkaufspreis(verkaufspreis) {} +}; + +std::ostream &operator<<(std::ostream &out, const Ware &ware); \ No newline at end of file diff --git a/Uebung 6/Uebung6_2/main.cpp b/Uebung 6/Uebung6_2/main.cpp new file mode 100644 index 0000000..ff94a3d --- /dev/null +++ b/Uebung 6/Uebung6_2/main.cpp @@ -0,0 +1,58 @@ +#include "ExtendedBinaryTree.h" +#include "ExtendedBinaryTreeNode.h" +#include "Ware.h" +#include + +void generateRandomIntArray(int *array, int arrayLength) { + std::srand(time(NULL)); + for (int i = 0; i < arrayLength; i++) { + array[i] = rand() % 100000 + 1; + } +} + +int main() { + + // bez, sn, gw, ek, vk + Ware ware1("S", 1, 5.12, 10.37, 13.0); + Ware ware2("L", 2, 6.12, 1.37, 29.0); + Ware ware3("A", 3, 4.12, 9.37, 10.0); + Ware ware4("Z", 12, 1.12, 18.37, 19.0); + Ware ware5("LA", 27, 0.12, 13.37, 17.0); + Ware ware6("LC", 13, 13.12, 15.37, 16.0); + Ware ware7("ABC", 4, 7.12, 27.37, 35.0); + Ware ware8("C", 123, 9.12, 2.37, 4.0); + + int randInts[8]; + generateRandomIntArray(randInts, 8); + + // Händisch sortierte Prioritäten, um die Waren ihren Prioritäten entsprechend + // einzusortieren, damit die Heapbedingung nicht verletzt werden kann. + std::sort(randInts, randInts + 8); + + ExtendedBinaryTree tree(&ware1, randInts[0]); + // std::cout << tree.printPreorder() << std::endl << std::flush; + tree.insert(&ware2, randInts[1]); + // std::cout << tree.printPreorder() << std::endl << std::flush; + tree.insert(&ware3, randInts[2]); + // std::cout << tree.printPreorder() << std::endl << std::flush; + tree.insert(&ware4, randInts[3]); + // std::cout << tree.printPreorder() << std::endl << std::flush; + tree.insert(&ware5, randInts[4]); + // std::cout << tree.printPreorder() << std::endl << std::flush; + tree.insert(&ware6, randInts[5]); + // std::cout << tree.printInorder() << std::endl << std::flush; + tree.insert(&ware7, randInts[6]); + // std::cout << tree.printInorder() << std::endl << std::flush; + tree.insert(&ware8, randInts[7]); + std::cout << tree.printPreorder() << std::endl << std::flush; + + // std::cout << ware1 << std::endl; + // std::cout << tree.printPreorder() << std::endl; + // std::cout << tree.printPostorder() << std::endl; + // std::cout << tree.printPreorder() << "\n" << std::endl; + // std::cout << tree.printPostorder() << "\n" << std::endl; + // std::cout << tree.printInorder(); + std::cout << tree.printPriority() << std::endl; + + return 0; +} \ No newline at end of file