Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 293 additions & 0 deletions src/data_structure_implement/tree/bst.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
#include <iostream>
#include <stdexcept>
#include <algorithm>

using namespace std;

class BinarySearchTree {
public:
BinarySearchTree();
~BinarySearchTree();

bool insert(int value);
bool erase(int value);
bool contains(int value) const;

int& min();
int& max();

int size() const;
bool empty() const;

int height() const;

void clear();

void printInorder() const;
void printPreorder() const;
void printPostorder() const;

private:
struct Node {
int value;
Node* left;
Node* right;
};

Node* root;
int current_size;

Node* findNode(int value) const;
Node* findMinNode(Node* node) const;
Node* findMaxNode(Node* node) const;

Node* insertNode(Node* node, int value, bool& inserted);
Node* eraseNode(Node* node, int value, bool& erased);

void clearNode(Node* node);

int heightNode(Node* node) const;

void inorder(Node* node) const;
void preorder(Node* node) const;
void postorder(Node* node) const;
};
BinarySearchTree::BinarySearchTree() : root(nullptr), current_size(0) {}
BinarySearchTree::~BinarySearchTree() {
clear();
}

bool BinarySearchTree::insert(int value) {
bool inserted = false;
root = insertNode(root, value, inserted);
if (inserted) current_size++;
return inserted;
}
bool BinarySearchTree::erase(int value){
bool erased = false;
root = eraseNode(root, value, erased);
if (erased) current_size--;
return erased;
}
bool BinarySearchTree::contains(int value) const {
if (current_size == 0) return false;
return findNode(value) != nullptr;
}

int& BinarySearchTree::min() {
if (root == nullptr) {
throw out_of_range("BinarySearchTree is empty");
}
return findMinNode(root)->value;
}
int& BinarySearchTree::max() {
if (root == nullptr) {
throw out_of_range("BinarySearchTree is empty");
}
return findMaxNode(root)->value;
}

int BinarySearchTree::size() const {
return current_size;
}
bool BinarySearchTree::empty() const {
return current_size == 0;
}

int BinarySearchTree::height() const {
return heightNode(root);
}

void BinarySearchTree::clear() {
clearNode(root);
root = nullptr;
current_size = 0;
}

void BinarySearchTree::printInorder() const {
inorder(root);
cout << '\n';
}
void BinarySearchTree::printPreorder() const {
preorder(root);
cout << '\n';
}
void BinarySearchTree::printPostorder() const {
postorder(root);
cout << '\n';
}

BinarySearchTree::Node* BinarySearchTree::findNode(int value) const {

Node* ptr = root;
while (ptr != nullptr) {
if (ptr->value < value) {
ptr = ptr->right;
} else if (ptr->value > value) {
ptr = ptr->left;
} else {
return ptr;
}
}

return nullptr;
}
BinarySearchTree::Node* BinarySearchTree::findMinNode(Node* node) const {
if (node == nullptr) {
return nullptr;
}
Node *ptr = node;
while(ptr->left != nullptr) {
ptr = ptr->left;
}
return ptr;
}
BinarySearchTree::Node* BinarySearchTree::findMaxNode(Node* node) const {
if (node == nullptr) {
return nullptr;
}
Node *ptr = node;
while(ptr->right != nullptr) {
ptr = ptr->right;
}
return ptr;
}

BinarySearchTree::Node* BinarySearchTree::insertNode(Node* node, int value, bool& inserted) {
if (node == nullptr) {
inserted = true;
return new Node{value, nullptr, nullptr};
}

if (value < node->value) {
node->left = insertNode(node->left, value, inserted);
} else if (value > node->value) {
node->right = insertNode(node->right, value, inserted);
}

return node;
}
BinarySearchTree::Node* BinarySearchTree::eraseNode(Node* node, int value, bool& erased) {
if (node == nullptr) {
return nullptr;
}

if (value < node->value) {
node->left = eraseNode(node->left, value, erased);
} else if (value > node->value) {
node->right = eraseNode(node->right, value, erased);
} else {
erased = true;

if (node->left == nullptr && node->right != nullptr) {
Node *rightChild = node->right;
delete node;
return rightChild;
} else if (node->left != nullptr && node->right == nullptr) {
Node *leftChild = node->left;
delete node;
return leftChild;
} else if (node->left == nullptr && node->right == nullptr){
delete node;
return nullptr;
} else {
Node *minNode = findMinNode(node->right);
node->value = minNode->value;
bool trash = false;
node->right = eraseNode(node->right, node->value, trash);
}
}
return node;
}

void BinarySearchTree::clearNode(Node* node) {
if (node == nullptr) return;

clearNode(node->left);
clearNode(node->right);

delete node;
}

int BinarySearchTree::heightNode(Node* node) const {
if (node==nullptr) return -1;

int right = heightNode(node->right);
int left = heightNode(node->left);

return std::max(right,left) + 1;
}

void BinarySearchTree::inorder(Node* node) const {
if (node == nullptr) return;

inorder(node->left);
cout << node->value << ' ';
inorder(node->right);
}
void BinarySearchTree::preorder(Node* node) const {
if (node == nullptr) return;

cout << node->value << ' ';
preorder(node->left);
preorder(node->right);
}
void BinarySearchTree::postorder(Node* node) const {
if (node == nullptr) return;

postorder(node->left);
postorder(node->right);
cout << node->value << ' ';
}
int main() {
BinarySearchTree tree;

tree.insert(10);
tree.insert(5);
tree.insert(15);
tree.insert(3);
tree.insert(7);
tree.insert(12);
tree.insert(20);
tree.insert(6);
tree.insert(8);

cout << "Inorder: ";
tree.printInorder();

cout << "Preorder: ";
tree.printPreorder();

cout << "Postorder: ";
tree.printPostorder();

cout << "size: " << tree.size() << '\n';
cout << "height: " << tree.height() << '\n';
cout << "min: " << tree.min() << '\n';
cout << "max: " << tree.max() << '\n';

cout << boolalpha;
cout << "contains 7: " << tree.contains(7) << '\n';
cout << "contains 100: " << tree.contains(100) << '\n';

cout << "\nerase leaf 3\n";
tree.erase(3);
tree.printInorder();

cout << "\nerase node with one child 5\n";
tree.erase(5);
tree.printInorder();

cout << "\nerase node with two children 10\n";
tree.erase(10);
tree.printInorder();

cout << "\nsize: " << tree.size() << '\n';
cout << "height: " << tree.height() << '\n';

tree.clear();

cout << "empty after clear: " << tree.empty() << '\n';

return 0;
}
Loading