Problem z drzewem binarnym

0

Cześć, mam problem z implementacją drzewa binarnego.

#include <iostream>

using namespace std;

struct binarySearchTree {
    int value;
    binarySearchTree *left;
    binarySearchTree *right;
};

binarySearchTree *root = NULL;

void insertNode(binarySearchTree *newNode) {

    //jeżeli dodajemy pierwszy element do drzewa to musi być to oddzielna instrukcja
    if(root == NULL) {
        root = newNode;
    }

    //jeżeli dodajemy element przynajmniej drugi to ...
    else {

        //dodatkowy wskaźnik do poruszania się po wartościach w drzewie i porównywania ich z nowo dokładanym elementem
        binarySearchTree *temp = root;

        //porównujemy elementy znajdujące się w drzewie z nowo wsadzanym elementem, dopóki nie osiągniemy dna drzewa (nowy elementem musi stać się liściem drzewa)
        while(temp != NULL)
        {
            //Pierwszy przypadek - nowo dodany element jest równy elementowi porównywanemu
            if(newNode->value == temp->value) {
                cout << "Drzewo binarne nie moze posiadac duplikatow c:" << endl;
                exit(0);
            }

            //Drugi przypadek - nowo dodany element jest mniejszy od elementu, z którym go porównujemy i miejsce na lewo jest puste, więc możemy tam go wstawić
            //drugi warunek jest konieczny, aby porównywać kolejne elementy (gdyby go nie było to nadpisywalibyśmy elementy)
            else if(newNode->value < temp->value) {

                if(temp->left == NULL) {
                    temp->left = newNode;
                    break;
                }

                else {
                    temp = temp->left;
                }
            }

            //Drugi warunek - nowo dodany element jest większy od elementu, z którym go porównujemy i miejsce na prawo jest puste, więc możemy tam go wstawić
            //drugi warunek jest konieczny, aby porównywać kolejne elementy (gdyby go nie było to nadpisywalibyśmy elementy)
            else if(newNode->value > temp->value) {

                if(temp->right == NULL) {
                    temp->right = newNode;
                    break;
                }

                else {
                    temp = temp->right;
                }
            }

        }
    }
}

//1. Sprawdź, czy istnieje lewy
//2. Wypisz
//3. Sprawdź, czy istnieje prawy
void printInorder(binarySearchTree *node)
{
    //dno rekurencji - jeśli nie ma ani lewego, ani prawego to cofnij się
    if(node == NULL)
        return;

    //sprawdzam, czy istnieje lewy
    printInorder(node->left);

    //wypisuje wartość
    cout << node->value << ' ';

    //sprawdzam, czy istnieje prawy
    printInorder(node->right);
}

//1. wypisz
//2. Sprawdź, czy lewy istnieje
//3. Sprawdź, czy prawy istnieje
void printPreorder(binarySearchTree *node)
{
    //dno rekurencji - jeśli nie ma ani lewego, ani prawego to cofnij się
    if(node == NULL)
        return;

    //wypisuje
    cout << node->value << ' ';

    //sprawdzam, czy istnieje lewy
    printPreorder(node->left);

    //sprawdzam, czy istnieje prawy
    printPreorder(node->right);

}

//1. Sprawdź, czy lewy istnieje
//2. Sprawdź, czy prawy istnieje
//3. wypisuje
void printPostorder(binarySearchTree *node)
{
    //dno rekurencji - jeśli nie ma ani lewego, ani prawego to cofnij się
    if(node == NULL)
        return;

    //sprawdzam, czy istnieje lewy
    printPostorder(node->left);

    //sprawdzam, czy istnieje prawy
    printPreorder(node->right);

    //wypisuje
    cout << node->value << ' ';

}

int main()
{
    binarySearchTree *newNode = new binarySearchTree;

    int input;
    while(input != -999)
    {
        cin >> input;

        newNode->value = input;

        insertNode(newNode);
    }

    printInorder(root);
    printPreorder(root);
    printPostorder(root);

    //1.inorder
    //2.preorder
    //3.postorder

    return 0;
}

Problem jest zdefiniowany tak:Zrzut ekranu 2022-04-06 220139.png

Inspirowałem się rozwiązaniem algorytmu z tego filmu:
Funkcje wypisujące drzewo są chyba okej. Z tego co widzę to jest jakiś problem ze wskaźnikiem na korzeń drzewa ale nie jestem pewien i nie wiem jak ten problem rozwiązać.
Potrafiłby mi to ktoś wyjaśnić i ewentualnie poprawić ? Z góry dzięki

2

Z tego co widzę to jest jakiś problem ze wskaźnikiem na korzeń drzewa ale nie jestem pewien i nie wiem jak ten problem rozwiązać.

Jakie wskazówki kierują Cię w stronę korzenia? Skoro nie wiesz jaki jest problem, to skąd wiesz, że nie wiesz jak go rozwiązać?

Anyway, na pewno masz bład w main, próbujesz dodać w kółko ten sam node, ale z inną wartością. Zamiast

    binarySearchTree *newNode = new binarySearchTree;

    int input;
    while(input != -999)
    {
        cin >> input;

        newNode->value = input;

        insertNode(newNode);
    }

Powinieneś mieć

    int input;
    while(input != -999)
    {
        cin >> input;

        binarySearchTree *newNode = new binarySearchTree;
        newNode->value = input;

        insertNode(newNode);
    }

Nie analizowałem samego dodawania, być może to nie jest jedyny problem.

2

Uwaga notacyjna: używasz "drzewo binarne", i "drzewo przeszukiwań binarnych" zamiennie. Drzewo binarne nie ma żadnego niezmiennika na elementy w wierzchołkach. Nie ma też żadnych ograniczeń w stylu "nie można mieć powtórzonych elementów".

Uwaga praktyczna: pewnie chcesz zrobić

binarySearchTree *newNode = new binarySearchTree;
newNode->value = input;
newNode->left = newNode->right = NULL;
1

Globalny root ... dalekie to od dobrego rozwiazania.

Kolejna zmarnowana szansa, jak można to choć trochę lepiej napisać w C++.
Tu jest język: C z new

0

OMG! Czy ty naprawdę chcesz uczyć się na filmie hinduskim?

0

Z takimi rzeczami jak sobie pościelisz tak się wyśpisz, porównaj ilość kodu i zastanów się czy warto słuchać hindusów:

#include<iostream>
using namespace std;

enum BsOrder { pre,in,post };

struct BsNode
{
    int value;
    BsNode *left,*right;
};
struct BsTree { BsNode *root; };

void BsInsertNode(BsNode **parent,int value)
{
	while(*parent)
	{
		if(value>(*parent)->value) parent=&((*parent)->right);
		else if(value<(*parent)->value) parent=&((*parent)->left);
		else return; //ignorujemy duplikaty
	}
	*parent=new BsNode {value,nullptr,nullptr};
}

void BsInsertNode(BsTree &tree,int value) { BsInsertNode(&tree.root,value); }

void BsShow(const BsNode *node,BsOrder order)
{
	if(order==pre) cout<<node->value<<' ';
	if(node->left) BsShow(node->left,order);
	if(order==in) cout<<node->value<<' ';
	if(node->right) BsShow(node->right,order);
	if(order==post) cout<<node->value<<' ';
}

void BsShow(const BsTree &tree,BsOrder order) { BsShow(tree.root,order); cout<<endl; }

int main()
{
	//6 3 7 2 5 8 -999
	BsTree tree {nullptr};
	for(int value;(cin>>value)&&(value!=-999);) BsInsertNode(tree,value);	
	BsShow(tree,BsOrder::in);
	BsShow(tree,BsOrder::pre);
	BsShow(tree,BsOrder::post);
	return 0;
}
0

Czy ja dobrze widzę w tym wątku, czy ja tu widzę, global root? :D

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