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

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

struct Node {
  int key;
  Node *parent, *right, *left;

public:
  Node(Node *r, Node *l, Node *p, int k)
      : right(r), left(l), parent(p), key(k){};
};

Node *root, *NIL;

void insert(int key) {
  Node *z = new Node(NIL, NIL, NIL, key);
  Node *y = NIL;
  Node *x = root;
  while (x != 0) {
    y = x;
    if (z->key < x->key) {
      x = x->left;
    } else {
      x = x->right;
    }
  }
  z->parent = y;
  if (y == NIL) {
    root = z;
  } else if (z->key < y->key) {
    y->left = z;
  } else {
    y->right = z;
  }
  return;
}

Node *find(Node *u, int key) {
  while (u != NIL && key != (u->key)) {
    if (key < (u->key))
      u = u->left;
    else
      u = u->right;
  }
  return u;
}

void inorder(Node *u) {
  if (u == NIL)
    return;
  inorder(u->left);
  cout << " " << u->key;
  inorder(u->right);
  return;
}

void preorder(Node *u) {
  if (u == NIL)
    return;
  cout << " " << u->key;
  preorder(u->left);
  preorder(u->right);
  return;
}

void print(Node *u) {
  inorder(root);
  cout << endl;
  preorder(root);
  cout << endl;
  return;
}

Node *successor(Node *u) {
  if (u->right != NIL) {
    Node *x;
    x = u->right;
    while (x->left != NIL)
      x = x->left;
    return x;
  }
  Node *y = u->parent;
  while (y != NIL && u == y->right) {
    u = y;
    y = y->parent;
  }
  return y;
}

void deleteNode(Node *u) {
  Node *y;
  Node *x;
  if (u->left == NIL || u->right == NIL)
    y = u;
  else
    y = successor(u);
  if (y->left != NIL)
    x = y->left;
  else
    x = y->right;
  if (x != NIL)
    x->parent = y->parent;
  if (y->parent == NIL)
    root = x;
  else {
    if (y == y->parent->left)
      y->parent->left = x;
    else
      y->parent->right = x;
  }
  if (y != u)
    u->key = y->key;
  free(y);
}
int main() {
  int n, key;
  string order;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> order;
    if (order == "insert") {
      cin >> key;
      insert(key);
    } else if (order == "delete") {
      cin >> key;
      deleteNode(find(root, key));
    } else if (order == "print") {
      print(root);
    } else if (order == "find") {
      cin >> key;
      if (find(root, key) != NIL)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <string>
using namespace std;

struct Node {
  int key;
  Node *parent, *right, *left;

public:
  Node(Node *r, Node *l, Node *p, int k)
      : right(r), left(l), parent(p), key(k){};
};

Node *root, *NIL;

void insert(int key) {
  Node *z = new Node(NIL, NIL, NIL, key);
  Node *y = NIL;
  Node *x = root;
  while (x != 0) {
    y = x;
    if (z->key < x->key) {
      x = x->left;
    } else {
      x = x->right;
    }
  }
  z->parent = y;
  if (y == NIL) {
    root = z;
  } else if (z->key < y->key) {
    y->left = z;
  } else {
    y->right = z;
  }
  return;
}

Node *find(Node *u, int key) {
  while (u != NIL && key != (u->key)) {
    if (key < (u->key))
      u = u->left;
    else
      u = u->right;
  }
  return u;
}

void inorder(Node *u) {
  if (u == NIL)
    return;
  inorder(u->left);
  cout << " " << u->key;
  inorder(u->right);
  return;
}

void preorder(Node *u) {
  if (u == NIL)
    return;
  cout << " " << u->key;
  preorder(u->left);
  preorder(u->right);
  return;
}

void print(Node *u) {
  inorder(root);
  cout << endl;
  preorder(root);
  cout << endl;
  return;
}

Node *successor(Node *u) {
  if (u->right != NIL) {
    while (u->left != NIL)
      u = u->left;
  }
  Node *y = u->parent;
  while (y != NIL && u == y->right) {
    u = y;
    y = y->parent;
  }
  return y;
}

void deleteNode(Node *u) {
  Node *y;
  Node *x;
  if (u->left == NIL || u->right == NIL)
    y = u;
  else
    y = successor(u);
  if (y->left != NIL)
    x = y->left;
  else
    x = y->right;
  if (x != NIL)
    x->parent = y->parent;
  if (y->parent == NIL)
    root = x;
  else {
    if (y == y->parent->left)
      y->parent->left = x;
    else
      y->parent->right = x;
  }
  if (y != u)
    u->key = y->key;
  delete y;
}
int main() {
  int n, key;
  string order;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> order;
    if (order == "insert") {
      cin >> key;
      insert(key);
    } else if (order == "delete") {
      cin >> key;
      deleteNode(find(root, key));
    } else if (order == "print") {
      print(root);
    } else if (order == "find") {
      cin >> key;
      if (find(root, key) != NIL)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    }
  }
  return 0;
}