Files
BinarySearchTree/README.md

149 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/postorder) 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 <cstddef>
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 <iostream>
#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
- **Preorder:** Rot → Vänster → Höger
- **Inorder:** Vänster → Rot → Höger (ger sorterad ordning för BST)
- **Postorder:** 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<char*>(&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
- **Nullskydd 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.