This commit is contained in:
2025-02-21 13:17:35 +01:00
commit e6bb2d584f
135 changed files with 141834 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(P1_2_Binaerbaum)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(P1_2_Binaerbaum main.cpp Tree.cpp TreeNode.cpp TreeTest.cpp)

View File

@@ -0,0 +1,18 @@
A;70;0;0
A;20;0;0
A;90;0;0
A;10;0;0
A;60;0;0
A;80;0;0
A;91;0;0
A;40;0;0
A;84;0;0
A;95;0;0
A;30;0;0
A;50;0;0
A;82;0;0
A;86;0;0
A;93;0;0
A;96;0;0
A;92;0;0
A;94;0;0
1 A 70 0 0
2 A 20 0 0
3 A 90 0 0
4 A 10 0 0
5 A 60 0 0
6 A 80 0 0
7 A 91 0 0
8 A 40 0 0
9 A 84 0 0
10 A 95 0 0
11 A 30 0 0
12 A 50 0 0
13 A 82 0 0
14 A 86 0 0
15 A 93 0 0
16 A 96 0 0
17 A 92 0 0
18 A 94 0 0

333
P1/ADS_P1_2_Binaerbaum/Tree.cpp Executable file
View File

@@ -0,0 +1,333 @@
/*************************************************
* ADS Praktikum 1.2
* Tree.cpp
* Erweiterung um Hilfsfunktionen gestattet.
*************************************************/
#include "Tree.h"
#include "TreeNode.h"
#include <iomanip>
#include <iostream>
#include <queue>
using namespace std;
Tree::Tree() {
currentNodeChronologcalID = 0;
}
Tree::~Tree() {
while (m_anker != nullptr) {
deleteNode(m_anker->getNodeOrderID());
}
}
TreeNode* Tree::getAnker() {
return m_anker;
}
void Tree::setAnker(TreeNode* node) {
m_anker = node;
}
void Tree::addNode(string Name, int Age, double Income, int PostCode) {
TreeNode* newNode = new TreeNode { Age + int(Income) + PostCode , currentNodeChronologcalID++, Name, Age, Income, PostCode };
TreeNode* ptr = getAnker();
TreeNode* tmp = nullptr;
/*
* Allg. Baumaufbau
* Anker
* klein -> groß
*/
// bis zum passenden Parentknoten traversieren
while (ptr != nullptr) {
tmp = ptr;
// wenn NodeID > ptrID dann rechts sonst links
// Dublikate?
newNode->getNodeOrderID() > ptr->getNodeOrderID() ?
ptr = ptr->getRight() : ptr = ptr->getLeft();
}
if (getAnker() == nullptr)
setAnker(newNode);
// wenn NodeID > tmpID dann rechts sonst links
else newNode->getNodeOrderID() > tmp->getNodeOrderID() ?
tmp->setRight(newNode) : tmp->setLeft(newNode);
}
bool Tree::deleteNode(int delNodeID) {
// Baum ist leer
if (!getAnker())
return false;
// Loeschen von Nodes - ab Wurzel
if (getAnker()->getNodeOrderID() == delNodeID) {
// 1. Fall: der Baum bestehet aus 1 Knoten.
if (!getAnker()->getRight() && !getAnker()->getLeft()) {
delete getAnker();
setAnker(nullptr);
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
// 2. Fall: Wurzel, mit einem Nachfolger
else if ((getAnker()->getRight() && !getAnker()->getLeft()) || (!getAnker()->getRight() && getAnker()->getLeft())) {
TreeNode* tmp = getAnker();
// Nachfolger wird Anker
getAnker()->getRight() ?
setAnker(getAnker()->getRight()) : setAnker(getAnker()->getLeft());
delete tmp;
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
// 3. Fall: Wurzel, mit zwei Nachfolger
else if (getAnker()->getRight() && getAnker()->getLeft()) {
TreeNode* minimumRTB = getAnker()->getRight();
TreeNode* minimumParent = nullptr;
// Minimum von RTB suchen.
while (minimumRTB->getLeft() != nullptr) {
minimumParent = minimumRTB;
minimumRTB = minimumRTB->getLeft();
}
// Minimum von RTB gefunden
if (minimumParent != nullptr) {
minimumParent->setLeft(minimumRTB->getRight());
minimumRTB->setLeft(getAnker()->getLeft());
minimumRTB->setRight(getAnker()->getRight());
}
// Minimum von RTB ist RTB-Wurzel (RTB->left == nullptr)
else
minimumRTB->setLeft(getAnker()->getLeft());
delete getAnker();
setAnker(minimumRTB);
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
}
// Loeschen von Nodes - Node != Wurzel
else {
// zu loeschende Node und Parent_Node
TreeNode* ptr = getAnker();
TreeNode* parent = getAnker();
// suche zuloeschenden Node
while ((ptr->getRight() || ptr->getLeft()) && ptr->getNodeOrderID() != delNodeID && ptr) {
parent = ptr;
delNodeID < ptr->getNodeOrderID() ?
ptr = ptr->getLeft() : ptr = ptr->getRight();
}
// 1. Fall Loeschen von Nodes - ohne Nachfolger
if (!ptr->getRight() && !ptr->getLeft()) {
parent->getNodeOrderID() < ptr->getNodeOrderID() ?
parent->setRight(nullptr) : parent->setLeft(nullptr);
delete ptr;
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
// 2. Fall Loeschen von Nodes - mit einem Nachfolger
else if ((!ptr->getRight() && ptr->getLeft()) || (ptr->getRight() && !ptr->getLeft())) {
if (parent->getNodeOrderID() < ptr->getNodeOrderID())
ptr->getRight() ?
parent->setRight(ptr->getRight()) : parent->setRight(ptr->getLeft());
else
ptr->getRight() ?
parent->setLeft(ptr->getRight()) : parent->setLeft(ptr->getLeft());
delete ptr;
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
// 3. Fall Loeschen von Nodes - mit zwei Nachfolger
if (ptr->getRight() != nullptr && ptr->getLeft() != nullptr) {
TreeNode* minimumRTB = ptr->getRight();
TreeNode* minimumParent = nullptr;
//Minumum von RTB suchen.
while (minimumRTB->getLeft() != nullptr) {
minimumParent = minimumRTB;
minimumRTB = minimumRTB->getLeft();
}
//Minimum von RTB gefunden
if (minimumParent != nullptr) {
minimumParent->setLeft(minimumRTB->getRight());
minimumRTB->setLeft(ptr->getLeft());
minimumRTB->setRight(ptr->getRight());
}
//Minimum von RTB ist RTB-Wurzel (RTB->left == nullptr)
else
minimumRTB->setLeft(ptr->getLeft());
//verknuepfe parent von zu loeschende Node
parent->getNodeOrderID() < ptr->getNodeOrderID() ?
parent->setRight(minimumRTB) :
parent->setLeft(minimumRTB);
delete ptr;
cout << "+ Datensatz wurde gelöscht.\n";
return true;
}
}
return false;
}
bool Tree::searchNode(std::string name) {
// Baum muss vorhanden sein
if (getAnker() != nullptr) {
bool found = false;
TreeNode* ptr = getAnker();
TreeNode* node;
cout << endl <<
"ID | Name | Alter | Einkommen | PLZ | OrderID\n"
"---+------------+-------+-----------+-------+--------\n";
queue<TreeNode*> q;
q.push(ptr);
while (!q.empty()) {
node = q.front();
q.pop();
if (node->getName() == name) {
printNode(node);
found = true;
// break; // damit werden alle Knoten mit dem Namen ausgegeben
}
if (node->getLeft() != nullptr)
q.push(node->getLeft());
if (node->getRight() != nullptr)
q.push(node->getRight());
}
if (!found)
cout << "--------------- Kein Eintrag vorhanden --------------" << endl;
return found;
}
else
return false;
}
void Tree::printNode(TreeNode* node) {
cout << setw(3) << node->getNodeChronologicalID() << '|' << setw(12) << node->getName() << '|'
<< setw(7) << node->getAge() << '|' << setw(11) << node->getIncome() << '|'
<< setw(7) << node->getPostCode() << '|' << setw(8) << node->getNodeOrderID() << endl;
}
void Tree::printLevelOrder() {
TreeNode* root = getAnker();
// 2 Queues instanzieren
std::queue<TreeNode*> q;
std::queue<int> nq;
cout << endl <<
"ID | Name | Alter | Einkommen | PLZ | OrderID\n"
"---+------------+-------+-----------+-------+--------\n";
if (root == nullptr) {
cout << "--------------- Kein Eintrag vorhanden --------------" << endl;
return;
}
// Wurzelknoten und Startniveau in die Queues pushen
q.push(root);
nq.push(0);
// vorheriges Niveau merken bzw. den Niveauwechsel irgendwie mitbekommen
int prev_niveau = -1;
int niveau;
// Schleife
while (!q.empty()) {
// Entnahme aus den Queues und loeschen
TreeNode* ptr = q.front();
q.pop();
niveau = nq.front();
nq.pop();
// Ausgabe Niveauwechsel
if (prev_niveau != niveau) {
std::cout << std::endl << "Niveau " << niveau << ": " << endl;
prev_niveau = niveau;
}
// Ausgabe des Knotens
printNode(ptr);
// Linker Nachfolgeknoten in die Queues
if (ptr->getLeft() != nullptr) {
q.push(ptr->getLeft());
nq.push(niveau + 1);
}
// Rechter Nachfolgeknoten in die Queues
if (ptr->getRight() != nullptr) {
q.push(ptr->getRight());
nq.push(niveau + 1);
}
}
}
void Tree::printPreOrder(TreeNode* ptr) {
if (ptr != nullptr) {
printNode(ptr);
printPreOrder(ptr->getLeft());
printPreOrder(ptr->getRight());
}
}
void Tree::printPostOrder(TreeNode* ptr) {
if (ptr != nullptr) {
printPreOrder(ptr->getLeft());
printPreOrder(ptr->getRight());
printNode(ptr);
}
}
void Tree::printInOrder(TreeNode* ptr) {
if (ptr != nullptr) {
printPreOrder(ptr->getLeft());
printNode(ptr);
printPreOrder(ptr->getRight());
}
}
void Tree::printAll() {
if (getAnker() != nullptr) {
string ausgabeFormat;
cout << "Ausgabereihenfolge ?> ";
cin >> ausgabeFormat;
TreeNode* ptr = getAnker();
cout << endl <<
"ID | Name | Alter | Einkommen | PLZ | OrderID\n"
"---+------------+-------+-----------+-------+--------\n";
if (ausgabeFormat == "pre")
printPreOrder(getAnker());
else if (ausgabeFormat == "post")
printPostOrder(getAnker());
else if (ausgabeFormat == "in")
printInOrder(getAnker());
else
cout << "falsches Formatkürzel";
}
else
cout << "--------------- Kein Eintrag vorhanden --------------\n";
}

35
P1/ADS_P1_2_Binaerbaum/Tree.h Executable file
View File

@@ -0,0 +1,35 @@
/*************************************************
* ADS Praktikum 1.2
* Tree.h
* Erweiterung um Hilfsattribute und -funktionen gestattet, wenn erforderlich.
*************************************************/
#pragma once
#include "TreeNode.h"
#include "catch.h"
#include <string>
using namespace std;
class Tree {
private:
TreeNode* m_anker = nullptr;
int currentNodeChronologcalID = 0;
public:
Tree();
~Tree();
void addNode(std::string Name, int Age, double Income, int PostCode);
bool deleteNode(int NodeOrderID);
bool searchNode(std::string Name);
void printAll();
void printNode(TreeNode* node);
void printPreOrder(TreeNode* ptr);
void printPostOrder(TreeNode* ptr);
void printInOrder(TreeNode* ptr);
void printLevelOrder();
TreeNode* getAnker();
void setAnker(TreeNode* _anker);
// friend-Funktionen sind für die Tests erforderlich und müssen unangetastet
// bleiben!
friend TreeNode* get_anker(Tree& TN);
};

View File

@@ -0,0 +1,86 @@
/*************************************************
* ADS Praktikum 1.2
* TreeNode.cpp
* Erweiterung um Hilfsfunktionen gestattet.
*************************************************/
#include "TreeNode.h"
#include <iostream>
#include <string>
TreeNode::TreeNode(int nNodePos,
int id,
string name,
int alter,
double einkommen,
int plz) {
this->m_NodeOrderID = nNodePos;
this->m_NodeChronologicalID = id;
this->m_Name = name;
this->m_Age = alter;
this->m_Income = einkommen;
this->m_PostCode = plz;
this->m_left = nullptr;
this->m_right = nullptr;
}
int TreeNode::getNodeOrderID() const {
return m_NodeOrderID;
}
int TreeNode::getNodeChronologicalID() const {
return m_NodeChronologicalID;
}
string TreeNode::getName() const {
return m_Name;
}
int TreeNode::getAge() const {
return m_Age;
}
double TreeNode::getIncome() const {
return m_Income;
}
int TreeNode::getPostCode() const {
return m_PostCode;
}
TreeNode* TreeNode::getLeft() {
return m_left;
}
TreeNode* TreeNode::getRight() {
return m_right;
}
void TreeNode::setNodeOrderID(int noID) {
m_NodeOrderID = noID;
}
void TreeNode::setName(string name) {
m_Name = name;
}
void TreeNode::setAge(int age) {
m_Age = age;
}
void TreeNode::setIncome(double income) {
m_Income = income;
}
void TreeNode::setPostCode(int postcode) {
m_PostCode = postcode;
}
void TreeNode::setLeft(TreeNode* node) {
m_left = node;
}
void TreeNode::setRight(TreeNode* node) {
m_right = node;
}
void print();

View File

@@ -0,0 +1,44 @@
/*************************************************
* ADS Praktikum 1.2
* TreeNode.h
* Erweiterung um Hilfsattribute und -funktionen gestattet, wenn erforderlich.
*************************************************/
#pragma once
#include <string>
using namespace std;
class TreeNode {
private:
int m_NodeOrderID;
int m_NodeChronologicalID;
string m_Name;
int m_Age;
double m_Income;
int m_PostCode;
TreeNode* m_left = nullptr;
TreeNode* m_right = nullptr;
public:
TreeNode(int, int, string, int, double, int);
int getNodeOrderID() const;
int getNodeChronologicalID() const;
string getName() const;
int getAge() const;
double getIncome() const;
int getPostCode() const;
TreeNode* getLeft();
TreeNode* getRight();
void setNodeOrderID(int noID);
void setName(string name);
void setAge(int age);
void setIncome(double income);
void setPostCode(int postcode);
void setLeft(TreeNode* node);
void setRight(TreeNode* node);
void print();
};

View File

@@ -0,0 +1,315 @@
/*************************************************
* ADS Praktikum 1.1
* Unit-Testdatei
* Stand: 12.04.2024
*
*************************************************
* Änderungen untersagt!
*************************************************/
#include "Tree.h"
#include "TreeNode.h"
#include "catch.h"
#include <iostream>
#include <string>
using namespace std;
// Friend-Methode fuer Testroutine
TreeNode* get_anker(Tree& Tr)
{
return Tr.m_anker;
}
/***********************************************
* Testroutine des Baums:
* - Einfaches Hinzufuegen und Suchen
* - Loeschen in unterscheidlicher Ausprägung
* + Loeschen ohne Nachfolger
* + Loeschen mit einem Nachfolger
* + Loeschen mit zwei Nachfolger
* + Loeschen der Wurzel
* - Hinzufuegen vieler Nodes als Grossbaum
*/
TEST_CASE("Tree Testing", "[TREE]")
{
Tree* nTree = new Tree();
SECTION("Hinzufuegen von Nodes und Suche - simple")
{
nTree->addNode("Mayer", 20, 0, 0);
nTree->addNode("Mayer2", 10, 0, 0);
nTree->addNode("Mayer3", 30, 0, 0);
nTree->addNode("Mayer4", 40, 0, 0);
nTree->addNode("Mayer5", 35, 0, 0);
nTree->addNode("Mayer6", 25, 0, 0);
nTree->addNode("Mayer7", 26, 0, 0);
REQUIRE(nTree->searchNode("Mayer") == true);
REQUIRE(nTree->searchNode("Mayer7") == true);
REQUIRE(nTree->searchNode("Mayer6") == true);
REQUIRE(nTree->searchNode("Mayer5") == true);
REQUIRE(nTree->searchNode("Mayer4") == true);
REQUIRE(nTree->searchNode("Mayer3") == true);
REQUIRE(nTree->searchNode("Mayer2") == true);
REQUIRE(nTree->searchNode("Mueller") == false);
REQUIRE(nTree->searchNode("Mayer99") == false);
}
SECTION("Loeschen von Nodes - ohne Nachfolger")
{
nTree->addNode("Mayer", 20, 0, 0);
nTree->addNode("Mayer2", 10, 0, 0);
nTree->addNode("Mayer3", 30, 0, 0);
nTree->addNode("Mayer4", 40, 0, 0);
nTree->addNode("Mayer5", 35, 0, 0);
nTree->addNode("Mayer6", 25, 0, 0);
nTree->addNode("Mayer7", 26, 0, 0);
nTree->addNode("Mayer8", 8, 0, 0);
REQUIRE(nTree->searchNode("Mayer8") == true);
TreeNode* tnanker = get_anker(*nTree);
nTree->deleteNode(8);
REQUIRE(tnanker->getLeft()->getLeft() == nullptr);
}
SECTION("Loeschen von Nodes - mit einem Nachfolger")
{
nTree->addNode("Mayer", 20, 0, 0);
nTree->addNode("Mayer2", 10, 0, 0);
nTree->addNode("Mayer3", 30, 0, 0);
nTree->addNode("Mayer4", 40, 0, 0);
nTree->addNode("Mayer5", 35, 0, 0);
nTree->addNode("Mayer6", 25, 0, 0);
nTree->addNode("Mayer7", 26, 0, 0);
nTree->addNode("Mayer8", 8, 0, 0);
nTree->addNode("Mayer9", 7, 0, 0);
REQUIRE(nTree->searchNode("Mayer8") == true);
REQUIRE(nTree->searchNode("Mayer9") == true);
TreeNode* tnanker = get_anker(*nTree);
// linke Seite
nTree->deleteNode(8);
REQUIRE(tnanker->getLeft()->getLeft() != nullptr);
REQUIRE(tnanker->getLeft()->getRight() == nullptr);
REQUIRE(tnanker->getLeft()->getLeft()->getNodeOrderID() == 7);
nTree->deleteNode(7);
REQUIRE(tnanker->getLeft()->getLeft() == nullptr);
REQUIRE(tnanker->getLeft()->getRight() == nullptr);
REQUIRE(tnanker->getLeft()->getNodeOrderID() == 10);
REQUIRE(nTree->searchNode("Mayer8") == false);
REQUIRE(nTree->searchNode("Mayer9") == false);
// rechte Seite
nTree->addNode("Mayer8", 8, 0, 0);
nTree->addNode("Mayer9", 9, 0, 0);
REQUIRE(nTree->searchNode("Mayer8") == true);
REQUIRE(nTree->searchNode("Mayer9") == true);
nTree->deleteNode(8);
REQUIRE(tnanker->getLeft()->getLeft() != nullptr);
REQUIRE(tnanker->getLeft()->getLeft()->getNodeOrderID() == 9);
nTree->deleteNode(9);
REQUIRE(tnanker->getLeft()->getLeft() == nullptr);
REQUIRE(tnanker->getLeft()->getNodeOrderID() == 10);
REQUIRE(nTree->searchNode("Mayer8") == false);
REQUIRE(nTree->searchNode("Mayer9") == false);
}
SECTION("Loeschen von Nodes - mit zwei Nachfolger")
{
nTree->addNode("Mayer", 20, 0, 0);
nTree->addNode("Mayer2", 10, 0, 0);
nTree->addNode("Mayer3", 30, 0, 0);
nTree->addNode("Mayer4", 40, 0, 0);
nTree->addNode("Mayer5", 35, 0, 0);
nTree->addNode("Mayer6", 25, 0, 0);
nTree->addNode("Mayer7", 26, 0, 0);
TreeNode* tnanker = get_anker(*nTree);
REQUIRE(tnanker->getNodeOrderID() == 20);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 30);
REQUIRE(tnanker->getRight()->getLeft()->getNodeOrderID() == 25);
REQUIRE(tnanker->getRight()->getLeft()->getRight()->getNodeOrderID() ==
26);
REQUIRE(tnanker->getRight()->getRight()->getLeft()->getNodeOrderID() ==
35);
nTree->deleteNode(30);
REQUIRE(tnanker->getNodeOrderID() == 20);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 35);
REQUIRE(tnanker->getRight()->getRight()->getNodeOrderID() == 40);
REQUIRE(tnanker->getRight()->getRight()->getLeft() == nullptr);
REQUIRE(tnanker->getRight()->getRight()->getRight() == nullptr);
REQUIRE(tnanker->getRight()->getLeft()->getNodeOrderID() == 25);
REQUIRE(tnanker->getRight()->getLeft()->getRight()->getNodeOrderID() ==
26);
REQUIRE(tnanker->getRight()->getLeft()->getLeft() == nullptr);
nTree->deleteNode(35);
REQUIRE(tnanker->getNodeOrderID() == 20);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 40);
REQUIRE(tnanker->getRight()->getLeft()->getNodeOrderID() == 25);
}
SECTION("Loeschen von Nodes - ab Wurzel")
{
nTree->addNode("Mayer", 20, 0, 0);
nTree->addNode("Mayer2", 10, 0, 0);
nTree->addNode("Mayer3", 30, 0, 0);
nTree->addNode("Mayer4", 40, 0, 0);
nTree->addNode("Mayer5", 35, 0, 0);
nTree->addNode("Mayer6", 25, 0, 0);
nTree->addNode("Mayer7", 26, 0, 0);
TreeNode* tnanker = get_anker(*nTree); // Initiale Übergrabe des Ankers
/*
Lösche den Baum schrittweise durch entfernen der Wurzel
*/
REQUIRE(tnanker->getNodeOrderID() == 20);
nTree->deleteNode(20);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 25);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 30);
REQUIRE(tnanker->getRight()->getLeft()->getNodeOrderID() == 26);
REQUIRE(tnanker->getRight()->getRight()->getNodeOrderID() == 40);
nTree->deleteNode(25);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 26);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 30);
REQUIRE(tnanker->getRight()->getLeft() == nullptr);
REQUIRE(tnanker->getRight()->getRight()->getNodeOrderID() == 40);
nTree->deleteNode(26);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 30);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 40);
REQUIRE(tnanker->getRight()->getLeft()->getNodeOrderID() == 35);
REQUIRE(tnanker->getRight()->getRight() == nullptr);
nTree->deleteNode(30);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 35);
REQUIRE(tnanker->getRight()->getNodeOrderID() == 40);
REQUIRE(tnanker->getRight()->getLeft() == nullptr);
REQUIRE(tnanker->getRight()->getRight() == nullptr);
nTree->deleteNode(35);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 40);
REQUIRE(tnanker->getRight() == nullptr);
REQUIRE(tnanker->getLeft()->getNodeOrderID() == 10);
nTree->deleteNode(40);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker->getNodeOrderID() == 10);
REQUIRE(tnanker->getRight() == nullptr);
REQUIRE(tnanker->getLeft() == nullptr);
nTree->deleteNode(10);
tnanker = get_anker(
*nTree); // Anker hat sich geändert, neue Übergabe erfoderlich
REQUIRE(tnanker == nullptr);
}
SECTION("Hinzufuegen von Nodes - Erzeuge Grossbaum")
{
for (int i = 0; i < 124; i++)
{
string info = "Name-" + to_string(i);
// Random Income und PostCode
double r = rand() + 1;
int PostCode = rand() + 1;
nTree->addNode(info, 0, r, PostCode);
}
nTree->printAll();
nTree->printLevelOrder();
std::cout << "========================================" << endl;
std::cout << "Testausgabe des Grossbaums abgeschlossen" << endl;
}
}
/***********************************************
* Testroutine des Knotens:
* - Einfaches pruefen der Getter und Setter in Ausführung
*/
TEST_CASE("TreeNode Testing", "[TREENODE]")
{
Tree* smallTree = new Tree();
smallTree->addNode("Herzog", 20, 0, 0);
TreeNode* ref = get_anker(*smallTree);
SECTION("Getter von TreeNode - simple")
{
REQUIRE(ref->getName() == "Herzog");
REQUIRE(ref->getAge() == 20);
REQUIRE(ref->getIncome() == 0);
REQUIRE(ref->getLeft() == nullptr);
REQUIRE(ref->getRight() == nullptr);
REQUIRE(ref->getNodeChronologicalID() == 0);
REQUIRE(ref->getNodeOrderID() == 20);
REQUIRE(ref->getPostCode() == 0);
}
SECTION("Setter von TreeNode - simple")
{
ref->setAge(22);
REQUIRE(ref->getAge() == 22);
ref->setIncome(1000);
REQUIRE(ref->getIncome() == 1000);
ref->setLeft(nullptr);
REQUIRE(ref->getLeft() == nullptr);
ref->setRight(nullptr);
REQUIRE(ref->getRight() == nullptr);
ref->setName("Kaiser");
REQUIRE(ref->getName() == "Kaiser");
ref->setPostCode(1000);
REQUIRE(ref->getPostCode() == 1000);
}
delete smallTree;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// http://www.hashemall.com/
// Zeile 1-311 hat den SHA 256 Hashwert:
// 2AD58F06D997AD8B7AABE694372CBEDF31F718B975E1F71A87C360B0DFA2B469

18182
P1/ADS_P1_2_Binaerbaum/catch.h Executable file

File diff suppressed because it is too large Load Diff

128
P1/ADS_P1_2_Binaerbaum/main.cpp Executable file
View File

@@ -0,0 +1,128 @@
/*************************************************
* ADS Praktikum 1.2
* main.cpp
*
*************************************************/
#define CATCH_CONFIG_RUNNER
#include "Tree.h"
#include "catch.h"
#include <iostream>
using namespace std;
///////////////////////////////////////
// Hilfsmethoden fürs Menü hier:
/***************************
** Vorgegebene Funktion **
***************************
"mainscreen_addTreeCSV"
Importiert CSV Datei in bestehenden Baum.
Bei Aufruf in der main() Methode, muss der Pointer auf den Anker des Baums, als Parameter übergeben werden.
Es wird die im gleichen Verzeichnis liegende Datei "ExportZielanalyse.csv" geladen.
****************************/
void mainscreen_addTreeCSV(Tree*& ref) {
char j;
cout << "+ Moechten Sie die Daten aus der Datei ExportZielanalyse.csv "
"importieren(j / n) ? >";
cin >> j;
if (j == 'j') {
ifstream csvread;
csvread.open("ExportZielanalyse.csv", ios::in);
if (!csvread.is_open()) {
cout << "Fehler beim Lesen!" << endl;
return;
}
else {
string name, age, postcode, income;
while (!csvread.eof()) {
getline(csvread, name, ';');
getline(csvread, age, ';');
getline(csvread, income, ';');
getline(csvread, postcode, '\n');
ref->addNode(name, stoi(age), stod(income), stoi(postcode));
}
csvread.close();
}
cout << "+ Daten wurden dem Baum hinzugefuegt." << endl;
}
}
int main() {
int result = Catch::Session().run();
Tree* Baum = new Tree();
int engb;
while(true){
cout << "====================================\n"
"1) Datensatz einfuegen, manuell\n"
"2) Datensatz einfuegen, CSV Datei\n"
"3) Datensatz loeschen\n"
"4) Suchen\n"
"5) Datenstruktur anzeigen (pre, post, in)\n"
"6) Level-Order anzeigen\n"
"7) Beenden\n"
"?> ";
cin >> engb;
switch (engb) {
case 1: {
string name;
int alter;
double einkommen;
int plz;
cout << "+ Bitte geben Sie die den Datensatz ein\n"
"Name ?> ";
cin >> name;
cout << "Alter ?> ";
cin >> alter;
cout << "Einkommen ?> ";
cin >> einkommen;
cout << "PLZ ?> ";
cin >> plz;
Baum->addNode(name, alter, einkommen, plz);
cout << "+ Ihr Datensatz wurde eingefuegt" << endl;
break;
}
case 2: {
mainscreen_addTreeCSV(Baum);
break;
}
case 3: {
int nodeOrderID;
cout << "+ Bitte geben Sie den zu loeschenden Datensatz an\n"
"OrderID ?> ";
cin >> nodeOrderID;
Baum->deleteNode(nodeOrderID);
break;
}
case 4: {
string name;
cout << "+ Bitte geben Sie den zu suchenden Datensatz an\n"
"Name ?> ";
cin >> name;
cout << "+ Fundstellen:\n";
Baum->searchNode(name);
break;
}
case 5: {
Baum->printAll();
break;
}
case 6: {
Baum->printLevelOrder();
break;
}
case 7:{
return 0;
}
}
};
system("PAUSE");
return 0;
}