Problem p02285 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <stdio.h>
#include <string>

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

Node *root, *NIL;
int n;

Node *getSuccessor(Node *u) {
  Node *x = u->right;
  while (x != NIL) {
    x = x->left;
  }
  return x;
}

void insert(int val) {
  Node *x = root;
  Node *y = NIL;
  Node *z;

  z = new Node();
  z->key = val;
  z->left = NIL;
  z->right = NIL;

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

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

void delete_Node(Node *u) {
  Node *y;
  Node *x;
  if (u->left != NIL && u->right != NIL) {
    y = getSuccessor(u);
  } else {
    y = 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;
}

Node *Find(Node *u, int val) {
  while (u != NIL) {
    if (u->key == val)
      return u;

    if (u->key > val) {
      u = u->left;
    } else if (u->key <= val) {
      u = u->right;
    }
  }
  return u;
}

void inorder(Node *u) {
  if (u == NIL)
    return;

  inorder(u->left);
  printf(" %d", u->key);
  inorder(u->right);
}

void preorder(Node *u) {
  if (u == NIL)
    return;

  printf(" %d", u->key);
  preorder(u->left);
  preorder(u->right);
}

void print() {
  inorder(root);
  printf("\n");
  preorder(root);
  printf("\n");
}

int main() {
  int val;
  char moji[10];

  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", moji);
    if (moji[0] == 'i') {
      scanf("%d", &val);
      insert(val);
    } else if (moji[0] == 'p') {
      print();
    } else if (moji[0] == 'f') {
      scanf("%d", &val);
      Node *u = Find(root, val);
      if (u == NIL)
        printf("no\n");
      else
        printf("yes\n");
    } else if (moji[0] == 'd') {
      scanf("%d", &val);
      delete_Node(Find(root, val));
    }
  }

  return 0;
}


Fixed submission:
#include <iostream>
#include <stdio.h>
#include <string>

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

Node *root, *NIL;
int n;

Node *getSuccessor(Node *u) {
  Node *x = u->right;
  while (x->left != NIL) {
    x = x->left;
  }
  return x;
}

void insert(int val) {
  Node *x = root;
  Node *y = NIL;
  Node *z;

  z = new Node();
  z->key = val;
  z->left = NIL;
  z->right = NIL;

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

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

void delete_Node(Node *u) {
  Node *y;
  Node *x;
  if (u->left != NIL && u->right != NIL) {
    y = getSuccessor(u);
  } else {
    y = 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;
}

Node *Find(Node *u, int val) {
  while (u != NIL) {
    if (u->key == val)
      return u;

    if (u->key > val) {
      u = u->left;
    } else if (u->key <= val) {
      u = u->right;
    }
  }
  return u;
}

void inorder(Node *u) {
  if (u == NIL)
    return;

  inorder(u->left);
  printf(" %d", u->key);
  inorder(u->right);
}

void preorder(Node *u) {
  if (u == NIL)
    return;

  printf(" %d", u->key);
  preorder(u->left);
  preorder(u->right);
}

void print() {
  inorder(root);
  printf("\n");
  preorder(root);
  printf("\n");
}

int main() {
  int val;
  char moji[10];

  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", moji);
    if (moji[0] == 'i') {
      scanf("%d", &val);
      insert(val);
    } else if (moji[0] == 'p') {
      print();
    } else if (moji[0] == 'f') {
      scanf("%d", &val);
      Node *u = Find(root, val);
      if (u == NIL)
        printf("no\n");
      else
        printf("yes\n");
    } else if (moji[0] == 'd') {
      scanf("%d", &val);
      delete_Node(Find(root, val));
    }
  }

  return 0;
}