Files
BinarySearchTree/README.md

4.7 KiB
Raw Blame History

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:

// 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:

#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++

g++ -std=c++17 -O2 -Wall -Wextra -o bst main.cpp tree.cpp
./bst

Med CMake (valfritt)

Skapa CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(bst LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(bst main.cpp tree.cpp)

Sedan:

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

fil.write((char*)&root->data, sizeof(root));

Detta är sannolikt en bugg sizeof(root) är storleken på pekaren, inte på data. Ändra till:

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.