# Binärt sökträd (C++) Ett enkelt projekt som implementerar ett **binärt sökträd (BST)** i C++. Koden innehåller grundläggande operationer som insättning, sökning, traversering (pre/in/post‑order) samt borttagning av noder. > **Notera:** I den kod som följde med finns referenser till `defs.h` samt typerna `dataType`, `ptrType` och klassen/structen `treeNode` som **inte** följde med i uppladdningen. README:n nedan utgår från hur gränssnittet ser ut i `tree.h`/`tree.cpp` och beskriver hur du kan komplettera. ## Filstruktur ``` . ├── tree.h └── tree.cpp ``` ### `tree.h` Deklarerar klassen `treeClass` med: - `ptrType root` – pekare till rotnoden - `seek`, `insert`, `del`, `delRoot`, `delLeft` – kärnoperationer - Traversering: `preOrder`, `inOrder`, `postOrder` - `save` – skriver trädets noder till en ström ### `tree.cpp` Definitioner för metoderna ovan. Använder `defs.h`, `dataType`, `ptrType` och `treeNode`: - `treeNode` förväntas vara en nod med fälten `data`, `left`, `right`. - `dataType` är datatypen som lagras i trädet (t.ex. `int` eller en struct med jämförelseoperatorer). - `ptrType` är sannolikt `treeNode*`. ## Förslag på kompletterande definitioner (`defs.h`) Skapa en enkel header så att projektet kompilerar. Exempel med heltal: ```cpp // defs.h #pragma once #include typedef int dataType; struct treeNode { dataType data; treeNode* left; treeNode* right; treeNode(dataType d, treeNode* L=nullptr, treeNode* R=nullptr) : data(d), left(L), right(R) {} }; using ptrType = treeNode*; #ifndef TRUE #define TRUE true #endif #ifndef FALSE #define FALSE false #endif ``` > I din `tree.cpp` finns redan en *medlemskonstruktör* för `treeNode` (`treeNode::treeNode(...)`), så du kan antingen: > 1) Låta konstruktorn bo i structen som ovan (rekommenderat) **och ta bort** den fristående definitionen i `tree.cpp`, **eller** > 2) Ha endast deklaration i `defs.h` och behålla definitionen i `tree.cpp`. ## Exempel på `main.cpp` Skapa ett minimalt körbart exempel: ```cpp #include #include "defs.h" #include "tree.h" int main() { treeClass t; // Bygg ett litet träd t.insert(t.root, 7); t.insert(t.root, 3); t.insert(t.root, 9); t.insert(t.root, 1); t.insert(t.root, 5); std::cout << "Inorder: "; t.inOrder(t.root); std::cout << "\n"; // Sök auto hit = t.seek(t.root, 5); std::cout << (hit ? "Hittade 5" : "Hittade inte 5") << "\n"; // Ta bort t.del(t.root, 3); std::cout << "Efter del(3), inorder: "; t.inOrder(t.root); std::cout << "\n"; return 0; } ``` ## Bygga & köra ### Med g++ ```bash g++ -std=c++17 -O2 -Wall -Wextra -o bst main.cpp tree.cpp ./bst ``` ### Med CMake (valfritt) Skapa `CMakeLists.txt`: ```cmake cmake_minimum_required(VERSION 3.15) project(bst LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) add_executable(bst main.cpp tree.cpp) ``` Sedan: ```bash cmake -S . -B build cmake --build build --config Release ./build/bst ``` ## Traverseringar - **Pre‑order:** Rot → Vänster → Höger - **In‑order:** Vänster → Rot → Höger (ger sorterad ordning för BST) - **Post‑order:** Vänster → Höger → Rot ## Borttagning (översikt) `del` hittar noden att ta bort, `delRoot` hanterar tre fall: 1. **Bladnod** → delete, sätt pekaren till `nullptr`. 2. **En ensam höger- eller vänstergren** → flytta upp barnpekaren. 3. **Två barn** → hämta minsta värdet i höger delträd (via `delLeft`), ersätt data och ta bort den noden. ## Serialisering (`save`) Metoden `save(ptrType root, std::fstream &fil)` försöker skriva data rekursivt. Just nu används ```cpp fil.write((char*)&root->data, sizeof(root)); ``` Detta är sannolikt en **bugg** – `sizeof(root)` är storleken på pekaren, inte på `data`. Ändra till: ```cpp fil.write(reinterpret_cast(&root->data), sizeof(root->data)); ``` Och tänk på **endianess**/typstorlek om filen ska vara portabel. För portabel serialisering, överväg textformat (t.ex. inorder-traversering till text) eller ett binärt, väldefinierat format. ## Kända förbättringar - **Null‑skydd i `del`**: Kontrollera att `root` inte är `nullptr` innan jämförelser. - **`isEmpty`** kan returnera `root == nullptr` direkt. - **Konstkorrekthet**: Markera lämpliga metoder som `const` där möjligt. - **Separera I/O**: Låt traversering skriva till en ström (`std::ostream&`) istället för `std::cout` direkt. - **Enhetstester**: Lägg till små tester som verifierar `insert/seek/del`. ## Licens Välj en licens (t.ex. MIT) och lägg i `LICENSE`. --- **Förslag:** Ladda gärna upp `defs.h` (och ev. `main.cpp`) så kan jag uppdatera README och lägga till exakta bygginstruktioner för ditt case.