Problem p02285 (C++) — buggy submission, verdict: Runtime Error

#include <iostream>
#include <memory>
#include <string>
#include <vector>

struct node {
  int key;
  std::weak_ptr<node> parent;
  std::shared_ptr<node> left;
  std::shared_ptr<node> right;
  node(int k) : key(k), left(nullptr), right(nullptr){};
};

class bst {
private:
  std::shared_ptr<node> root;
  void r_inorder(std::shared_ptr<node> n);
  void r_preorder(std::shared_ptr<node> n);

public:
  bst() : root(nullptr){};
  void insert(int v);
  bool find(int k);
  void delete_(int k);
  void print();
};

void bst::insert(int k) {
  std::shared_ptr<node> y = nullptr;
  std::shared_ptr<node> x = root;
  std::shared_ptr<node> z(new node(k));
  while (x != nullptr) {
    y = x;
    if (z->key < x->key)
      x = x->left;
    else
      x = x->right;
  }
  z->parent = y;
  if (y == nullptr)
    root = z;
  else if (z->key < y->key)
    y->left = z;
  else
    y->right = z;
}

bool bst::find(int k) {
  std::shared_ptr<node> n = root;
  while (n != nullptr) {
    if (n->key == k)
      return true;
    if (n->key > k)
      n = n->left;
    else
      n = n->right;
  }
  return false;
}

void bst::delete_(int k) {
  std::shared_ptr<node> n = root;
  while (n != nullptr) {
    if (n->key == k)
      break;
    if (n->key > k)
      n = n->left;
    else
      n = n->right;
  }
  if (n == nullptr)
    return;
  if (n->left == nullptr && n->right == nullptr) {
    auto p = n->parent.lock();
    if (p->left != nullptr && p->left->key == k) {
      p->left = nullptr;
    } else {
      p->right = nullptr;
    }
  } else if (n->left != nullptr && n->right != nullptr) {
    auto next = n->right;
    while (next->left != nullptr)
      next = next->left;
    int tmp = next->key;
    delete_(tmp);
    n->key = tmp;
  } else {
    auto p = n->parent.lock();
    if (p->left != nullptr && p->left->key == k) {
      p->left = (n->left != nullptr) ? n->left : n->right;
      p->left->parent = p;
    } else {
      p->right = (n->left != nullptr) ? n->left : n->right;
      p->right->parent = p;
    }
  }
}

void bst::r_inorder(std::shared_ptr<node> n) {
  if (n == nullptr)
    return;
  r_inorder(n->left);
  std::cout << " " << n->key;
  r_inorder(n->right);
}

void bst::r_preorder(std::shared_ptr<node> n) {
  if (n == nullptr)
    return;
  std::cout << " " << n->key;
  r_preorder(n->left);
  r_preorder(n->right);
}

void bst::print() {
  r_inorder(root);
  std::cout << std::endl;
  r_preorder(root);
  std::cout << std::endl;
}

int main() {
  int n;
  std::cin >> n;
  bst tree;
  for (int i = 0; i < n; ++i) {
    std::string str;
    std::cin >> str;
    int k;
    switch (str[0]) {
    case 'i':
      std::cin >> k;
      tree.insert(k);
      break;
    case 'f':
      std::cin >> k;
      std::cout << (tree.find(k) ? "yes" : "no") << std::endl;
      break;
    case 'd':
      std::cin >> k;
      tree.delete_(k);
      break;
    case 'p':
      tree.print();
      break;
    default:
      break;
    }
  }
}

Error: -11

Fixed submission:

#include <iostream>
#include <memory>
#include <string>
#include <vector>

struct node {
  int key;
  std::weak_ptr<node> parent;
  std::shared_ptr<node> left;
  std::shared_ptr<node> right;
  node(int k) : key(k), left(nullptr), right(nullptr){};
};

class bst {
private:
  std::shared_ptr<node> root;
  void r_inorder(std::shared_ptr<node> n);
  void r_preorder(std::shared_ptr<node> n);

public:
  bst() : root(nullptr){};
  void insert(int v);
  bool find(int k);
  void delete_(int k);
  void print();
};

void bst::insert(int k) {
  std::shared_ptr<node> y = nullptr;
  std::shared_ptr<node> x = root;
  std::shared_ptr<node> z(new node(k));
  while (x != nullptr) {
    y = x;
    if (z->key < x->key)
      x = x->left;
    else
      x = x->right;
  }
  z->parent = y;
  if (y == nullptr)
    root = z;
  else if (z->key < y->key)
    y->left = z;
  else
    y->right = z;
}

bool bst::find(int k) {
  std::shared_ptr<node> n = root;
  while (n != nullptr) {
    if (n->key == k)
      return true;
    if (n->key > k)
      n = n->left;
    else
      n = n->right;
  }
  return false;
}

void bst::delete_(int k) {
  std::shared_ptr<node> n = root;
  while (n != nullptr) {
    if (n->key == k)
      break;
    if (n->key > k)
      n = n->left;
    else
      n = n->right;
  }
  if (n == nullptr)
    return;
  if (n->left == nullptr && n->right == nullptr) {
    auto p = n->parent.lock();
    if (p->left->key == k) {
      p->left = nullptr;
    } else {
      p->right = nullptr;
    }
  } else if (n->left != nullptr || n->right != nullptr) {
    int tmp = n->right->key;
    delete_(tmp);
    n->key = tmp;
  } else {
    auto p = n->parent.lock();
    if (p->left->key == k) {
      p->left = (n->left != nullptr) ? n->left : n->right;
    } else {
      p->right = (n->left != nullptr) ? n->left : n->right;
    }
  }
}

void bst::r_inorder(std::shared_ptr<node> n) {
  if (n == nullptr)
    return;
  r_inorder(n->left);
  std::cout << " " << n->key;
  r_inorder(n->right);
}

void bst::r_preorder(std::shared_ptr<node> n) {
  if (n == nullptr)
    return;
  std::cout << " " << n->key;
  r_preorder(n->left);
  r_preorder(n->right);
}

void bst::print() {
  r_inorder(root);
  std::cout << std::endl;
  r_preorder(root);
  std::cout << std::endl;
}

int main() {
  int n;
  std::cin >> n;
  bst tree;
  for (int i = 0; i < n; ++i) {
    std::string str;
    std::cin >> str;
    int k;
    switch (str[0]) {
    case 'i':
      std::cin >> k;
      tree.insert(k);
      break;
    case 'f':
      std::cin >> k;
      std::cout << (tree.find(k) ? "yes" : "no") << std::endl;
      break;
    case 'd':
      std::cin >> k;
      tree.delete_(k);
      break;
    case 'p':
      tree.print();
      break;
    default:
      break;
    }
  }
}