Drzewo genalogiczne w C++ - modyfikowanie osób

0

Próbuje zmodyfikować osobę w drzewie genealogicznym (case 3 w ostatnim pliku) jednak cały czas coś mi nie wychodzi. Zawsze wyrzuca błąd o niezainicjonowanej zmiennej lokalnej o. Nie rozumiem dlaczego dane się nie podmieniają. Gdzie popełniam błąd?

Plik bTree.h

#pragma once
#include <string>
#include <list>
#include <fstream>

struct osoba{
	std::string imie;
	std::string nazwisko;
	int rok_urodzenia;
	char plec; // K - kobieta, M - mężczyzna
};

struct node{
	osoba* data;
	node* parent;
	node* left_child;
	node* right_child;
	int poziom;
};

class bTree{
private:
	node* root;

public:
	//konstruktor i destruktor
	bTree();
	~bTree();

	//interfejs publiczy
	void add_root(osoba* o); //dodaje pierwszą osobę w drzewie
	void add_left_child(osoba* o, node* parent);  //dodanie mężczyzny (ojciec, dziadek, ...)
	void add_right_child(osoba* o, node* parent); //dodanie konbiety (matka, babcia, ...)
	void modify(std::string imie, std::string nazwisko, int rok, node* n);
	node* find(std::string imie, std::string nazwisko, int rok);
	void delete_leaf(node* n); //usunięcie liścia - tylko jednego węzła
	void delete_node(node* n); //usunięcie całego poddrzewa - kilka węzłów - trzeba uzyc postorder
	void delete_tree(node* bTree);          //usunięcie całego drzewa
	void print(node* n);

	node* get_root();
	bool isEmpty();

	std::list<node*> preorder(node* n, std::list<node*> lista_preorder); //metoda pomocnicza do wyświetlania drzewa

private:
	node* leftmost_child(node* n);
	node* right_sibling(node* n);
};

bTree.cpp

#include "bTree.h"

bTree::bTree(){
	root = nullptr;
}

bTree::~bTree(){
	//make_null();
}

void bTree::add_root(osoba* o){
	node* n = new node;
	n->data = o;
	n->parent = nullptr;
	n->left_child = nullptr;
	n->right_child = nullptr;
	root = n;
	n->poziom = 0;
}

node* bTree::get_root(){
	return root;
}

bool bTree::isEmpty(){
	return !root;
}

void bTree::add_left_child(osoba* o, node* parent){
	node* n = new node;
	n->data = o;
	n->left_child = nullptr;
	n->right_child = nullptr;
	n->parent = parent;
	parent->left_child = n;
	n->poziom = parent->poziom + 1;
}

void bTree::add_right_child(osoba* o, node* parent){
	node* n = new node;
	n->data = o;
	n->left_child = nullptr;
	n->right_child = nullptr;
	n->parent = parent;
	parent->right_child = n;
	n->poziom = parent->poziom + 1;
}

node* bTree::find(std::string imie, std::string nazwisko, int rok){
	node* p = root;
	while (p)
	{
		if (p->data->nazwisko == nazwisko)
		{
			if (p->data->imie == imie && p->data->rok_urodzenia == rok) return p;
			else p = p->left_child;
		}
		else
		{
			p = p->right_child;
		}
	}
	return p;
}

std::list<node*> bTree::preorder(node* n, std::list<node*> lista_preorder){
	lista_preorder.push_back(n);
	node* c = leftmost_child(n);
	while (c)
	{
		lista_preorder = preorder(c, lista_preorder);
		c = right_sibling(c);
	}
	return lista_preorder;
}

node* bTree::leftmost_child(node* n){
	if (n->left_child) return n->left_child;
	else if (n->right_child) return n->right_child;
	else return nullptr;
}

node* bTree::right_sibling(node* n){
	if (n == root) return nullptr;
	if (n == n->parent->right_child) return nullptr;
	return n->parent->right_child;
}

void bTree::delete_leaf(node* n) {
	if (n) {
		delete n->data;
		if (!n->parent) { //lisc jest rootem
			delete n;
			root = nullptr;
		}
		else if (n == n->parent->left_child) { //lisc jest lewym dzieckiem
			n->parent->left_child = nullptr;
			delete n;
		}
		else { //lisc jest prawym dzieckiem
			n->parent->right_child = nullptr;
			delete n;
		}
	}
}

void bTree::delete_tree(node* bTree) {
	if (bTree == nullptr) return;
	bTree->left_child;
	bTree->right_child;
	bTree->data;
	delete bTree->data;
	if (!bTree->parent) { 
		delete bTree;
		root = nullptr;
	}
}

plik glowny

#include "bTree.h"
#include <iostream>
#include <conio.h> //do getch()

using namespace std;

int main(){
	int opcja;
	string imie, nazwisko, imie1, nazwisko1;
	int rok, rok1;
	char plec;

	bTree drzewo_przodkow;

	do {
		cout << endl << "M E N U:" << endl;
		cout << "1 - Dodaj pierwsza osobe w drzewie" << endl;
		cout << "2 - Dodaj przodka" << endl;
		cout << "3 - Modyfikuj osobe" << endl;
		cout << "4 - Usun osobe oraz jej przodkow" << endl;
		cout << "5 - Usun cale drzewo" << endl;
		cout << "6 - Wypisz rodzicow podanej osoby" << endl;
		cout << "7 - Zapisz drzewo do pliku" << endl;
		cout << "8 - Wczytaj drzewo z pliku" << endl;
		cout << "9 - Wypisz drzewo" << endl;
		cout << "0 - KONIEC" << endl;

		cout << endl << "Podaj wybrana opcje: ";
		//cin >> opcja;
		opcja = _getch() - '0'; //działa bez entera
		cout << opcja << endl;

		switch (opcja){
		case 1:
			if (drzewo_przodkow.isEmpty()) {
				cout << endl;
				cout << "Podaj imie: ";
				cin >> imie;
				cout << "Podaj nazwisko: ";
				cin >> nazwisko;
				cout << "Podaj rok urodzenia: ";
				cin >> rok;
				cout << "Podaj plec (K - kobieta, M - mezczyzna): ";
				cin >> plec;
				cout << endl << imie << " " << nazwisko << ", ur. w " << rok << " roku" << endl;

				osoba* o = new osoba;
				o->imie = imie;
				o->nazwisko = nazwisko;
				o->rok_urodzenia = rok;
				o->plec = plec;
				drzewo_przodkow.add_root(o);
			}
			else
				cout << "Drzewo już istnieje, dodaj kolejne osoby" << endl;
			break;
		case 2:
			if (!drzewo_przodkow.isEmpty()){
				cout << endl;
				cout << "Nowa osoba: " << endl;
				cout << "Podaj imie: ";
				cin >> imie;
				cout << "Podaj nazwisko: ";
				cin >> nazwisko;
				cout << "Podaj rok urodzenia: ";
				cin >> rok;
				cout << "Podaj plec (K - kobieta, M - mezczyzna): ";
				cin >> plec;
				cout << endl << imie << " " << nazwisko << ", ur. w " << rok << " roku" << endl;

				osoba* o = new osoba;
				o->imie = imie;
				o->nazwisko = nazwisko;
				o->rok_urodzenia = rok;
				o->plec = plec;

				cout << endl << "Do jakiej osoby chcesz dodac przodka?" << endl;
				cout << "Wpisz: imie nazwisko i rok urodzenia tej osoby: ";
				cin >> imie >> nazwisko >> rok;
				node* n = drzewo_przodkow.find(imie, nazwisko, rok);
				if (!n){
					cout << endl << "Brak takiej osoby w drzewie" << endl;
					break;
				}
				if (o->plec == 'k' || o->plec == 'K') drzewo_przodkow.add_right_child(o, n);
				else drzewo_przodkow.add_left_child(o, n);

				cout << endl << "Dodano nowa osobe do drzewa" << endl;
			}
			break;
		case 3:
			if (!drzewo_przodkow.isEmpty()) {
				cout << endl;
				cout << "Podaj imie, nazwisko i rok urodzenia osoby ktora chcesz modyfikowac " << endl;
				cin >> imie >> nazwisko >> rok;
				node* n = drzewo_przodkow.find(imie, nazwisko, rok);
				if (n == nullptr)
				{
					cout << "Brak takiej osoby w drzewie" << endl;
					break;
				}
				cout << "Wprowadź zmiany. Podaj imie, nazwisko, rok urodzenia osoby: " << endl;
				cin >> imie1 >> nazwisko1 >> rok1;
				osoba* o;
				o->imie = imie1;
				o->nazwisko = nazwisko1;
				o->rok_urodzenia = rok1;
				drzewo_przodkow.modify(imie1, nazwisko1, rok1, n);
			}
			break;
		case 4:
			if (!drzewo_przodkow.isEmpty()) {
				cout << endl << "Jaka osobe chcesz usunac? (usuwa te osobe i wszystkich jej przodkow)" << endl;
				cout << "Wpisz: imie nazwisko i rok urodzenia tej osoby: ";
				cin >> imie >> nazwisko >> rok;
				node* n = drzewo_przodkow.find(imie, nazwisko, rok);
				drzewo_przodkow.delete_leaf(n);
				cout << endl << "Usunieto osobe z drzewa (oraz jej przodkow)" << endl;
			}
			break;

		case 5:
			if (!drzewo_przodkow.isEmpty()) {
				node* n = drzewo_przodkow.find(imie, nazwisko, rok);
				drzewo_przodkow.delete_tree(n);
				cout << "Drzewo zostalo usuniete!" << endl;
			} 
			break;
		case 6:


			break;
		case 7:

			break;
		case 8:

			break;
		case 9:
			/*if (!drzewo_przodkow.isEmpty()){
				cout << endl << drzewo_przodkow.get_root()->data->imie << " " << drzewo_przodkow.get_root()->data->nazwisko
					<< ", ur. w " << drzewo_przodkow.get_root()->data->rok_urodzenia << " roku" << endl;
				cout << drzewo_przodkow.get_root()->left_child->data->imie << " " << drzewo_przodkow.get_root()->left_child->data->nazwisko
					<< ", ur. w " << drzewo_przodkow.get_root()->left_child->data->rok_urodzenia << " roku" << endl;
			}*/


			list<node*> lista;
			lista = drzewo_przodkow.preorder(drzewo_przodkow.get_root(), lista);

			cout << endl << "D R Z E W O   G E N E A L O G I C Z N E" << endl;
			cout << "---------------------------------------" << endl;

			for (node* n : lista) {
				for (int i = 0; i < n->poziom; i++) cout << " ";
				cout << n->data->imie << " " << n->data->nazwisko << ", ur. " << n->data->rok_urodzenia << " r." << endl;
			}
			break;
		}

	} while (opcja != 0);

	return 0;
}
0

No linker bardzo wyraźnie Ci mówi co nie gra. Gdzie napisałeś metodę void bTree::modify(std::string imie, std::string nazwisko, int rok, node* n);?
EDIT: i na przyszłość: wklejaj błędy jakie dostajesz od kompilatora.

0

Dodałem to w taki sposób

void bTree::modify(std::string imie1, std::string nazwisko1, int rok1, node* n) {
	n->data->imie == imie1;
	n->data->nazwisko == nazwisko1;
	n->data->rok_urodzenia == rok1;
}

Jednak dalej pojawia się bląd w pliku głównym

Błąd C4700 użycie niezainicjowanej zmiennej lokalnej "o"

0

W okolicach linijki 104 mażesz po pamięci:

                osoba* o;
                o->imie = imie1;
                o->nazwisko = nazwisko1;
                o->rok_urodzenia = rok1;

EDIT: skompiluj to GCC z memory sanitizerem to zobaczysz błąd od razu.

0

No dobra sprawdziłem co się stanie po usunięciu tych linii i program działa, ale nie zmienia danych. W przypadku pierwszej osoby w drzewie, bo w przypadku jego "dzieci" niestety dostaje komunikat o braku takiej osoby w drzewie.

0

1.Największy problem jaki widzę jest taki, że źle wykonywane jest wyszukiwanie osoby/node w drzewie,
Założenie jest rozumiem takie, że jak znalezione zostało nazwisko to wyszukiwana jest dalej imię po stronie męskiej.
Czyli mężczyzna nie może zmienić nazwiska ??!!!! Naprawdę ??
Takie podejście rodzi zapewne i inne konsekwencje. Np. modyfikacja osoby np. poprzez zmianę nazwiska może całkowicie "popsuć" możliwość wyszukania osoby.

  1. Modyfikacja całkowicie nie bierze pod uwagę tego, że może została zmieniona płeć osoby. No przecież takie pomyłki też się zdarzają .. no i czasy też się zmieniły ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1