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

#include <iostream>
#include <string>

using namespace std;
struct Node {
  int key;
  Node *parent, *left, *right;
};

Node *root = NULL, *NIL = NULL;

void Preorder(Node *root) {
  if (root != NIL) {
    cout << " " << root->key;
    Preorder(root->left);
    Preorder(root->right);
  }
}

void Inorder(Node *root) {
  if (root != NIL) {
    Inorder(root->left);
    cout << " " << root->key;
    Inorder(root->right);
  }
}

void Postorder(Node *root) {
  if (root != NIL) {
    Postorder(root->left);
    Postorder(root->right);
    cout << " " << root->key;
  }
}
void insert(int key) {
  Node *p = new Node;
  p->key = key;
  p->left = NIL;
  p->right = NIL;

  Node *x = root;
  Node *y = NIL;

  while (x != NIL) {
    y = x;
    if (p->key > x->key)
      x = x->right;
    else
      x = x->left;
  }

  p->parent = y;
  if (y == NIL)
    root = p;
  else {
    if (p->key > y->key)
      y->right = p;
    else
      y->left = p;
  }
}

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

Node *getSuccesor(Node *p) {
  Node *y = p->right;
  while (y->left != NIL)
    y = y->left;

  return y;
}
void deleteNode(Node *p) {
  Node *y, *x; // y 为要删除的节点
  if (p->left == NIL || p->right == NIL)
    y = p;
  else
    y = getSuccesor(p);

  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 != p)
    p->key = y->key;

  delete y;
}

int main() {
  int n;
  string op;
  int key;

  cin >> n;
  while (n--) {
    cin >> op;
    if (op == "insert") {
      cin >> key;
      insert(key);
    } else if (op == "print") {
      Inorder(root);
      cout << endl;
      Preorder(root);
      cout << endl;
    } else if (op == "find") {
      cin >> key;
      if (find(key) != NIL)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    } else if (op == "delete") {
      cin >> key;

      deleteNode(find(key));
    }
  }
  return 0;
}


Error: -11

Fixed submission:

#include <iostream>
#include <string>

using namespace std;
struct Node {
  int key;
  Node *parent, *left, *right;
};

Node *root = NULL, *NIL = NULL;

void Preorder(Node *root) {
  if (root != NIL) {
    cout << " " << root->key;
    Preorder(root->left);
    Preorder(root->right);
  }
}

void Inorder(Node *root) {
  if (root != NIL) {
    Inorder(root->left);
    cout << " " << root->key;
    Inorder(root->right);
  }
}

void Postorder(Node *root) {
  if (root != NIL) {
    Postorder(root->left);
    Postorder(root->right);
    cout << " " << root->key;
  }
}
void insert(int key) {
  Node *p = new Node;
  p->key = key;
  p->left = NIL;
  p->right = NIL;

  Node *x = root;
  Node *y = NIL;

  while (x != NIL) {
    y = x;
    if (p->key > x->key)
      x = x->right;
    else
      x = x->left;
  }

  p->parent = y;
  if (y == NIL)
    root = p;
  else {
    if (p->key > y->key)
      y->right = p;
    else
      y->left = p;
  }
}

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

void deleteNode(Node *p) {
  Node *x = p->parent;
  Node *y = p->right;

  if (p = x->left)
    x->left = p->left;
  else if (p = x->right)
    x->right = p->left;

  p->left->right = y;

  delete p;
}

int main() {
  int n;
  string op;
  int key;

  cin >> n;
  while (n--) {
    cin >> op;
    if (op == "insert") {
      cin >> key;
      insert(key);
    } else if (op == "print") {
      Inorder(root);
      cout << endl;
      Preorder(root);
      cout << endl;
    } else if (op == "find") {
      cin >> key;
      if (find(key) != NIL)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    } else if (op == "delete") {
      cin >> key;

      deleteNode(find(key));
    }
  }
  return 0;
}