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

#include <cstdio>
#define MAXN 500000
struct node {
  int key;
  node *ch[2], *fa;
};
node tree[MAXN + 5];
bool first = true;
node *Root, *NIL, *ncnt;
void Init() {
  NIL = &tree[0];
  NIL->fa = NIL->ch[0] = NIL->ch[1] = NIL;
  ncnt = &tree[1];
  Root = NIL;
}
inline node *NewNode(int val) {
  node *p = ++ncnt;
  p->key = val;
  p->fa = p->ch[0] = p->ch[1] = NIL;
  return p;
}
void Insert(node *&rt, node *fa, int val) {
  if (rt == NIL) {
    rt = NewNode(val);
    rt->fa = fa;
    return;
  }
  int d = (val >= rt->key);
  Insert(rt->ch[d], rt, val);
}
void InOrder(node *rt) {
  if (rt == NIL)
    return;
  InOrder(rt->ch[0]);
  printf(" %d", rt->key);
  InOrder(rt->ch[1]);
}
void PreOrder(node *rt) {
  if (rt == NIL)
    return;
  printf(" %d", rt->key);
  PreOrder(rt->ch[0]);
  PreOrder(rt->ch[1]);
}
node *Find(node *rt, int val) {
  if (rt == NIL)
    return NIL;
  if (rt->key == val)
    return rt;
  int d = (val >= rt->key);
  return Find(rt->ch[d], val);
}
node *FindNext(node *rt) {
  if (rt == NIL)
    return NIL;
  node *y = rt->ch[1];
  while (y->ch[0] != NIL)
    y = y->ch[0];
  return y;
}
void Delete(node *rt, int val) {
  node *x, *y, *z = Find(rt, val);
  if (z == NIL)
    return;
  if (z->ch[0] == NIL || z->ch[1] == NIL)
    y = z;
  else
    y = FindNext(z);
  if (y->ch[0] != NIL)
    x = y->ch[0];
  else
    x = y->ch[1];
  if (x != NIL)
    x->fa = y->fa;
  if (y->fa == NIL)
    Root = x;
  else {
    int d = (y == y->fa->ch[1]);
    y->fa->ch[d] = x;
  }
  if (y != z)
    z->key = y->key;
}
int main() {
  int n, x;
  char op[100];
  Init();
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", op);
    if (op[0] == 'p') {
      InOrder(Root);
      puts("");
      PreOrder(Root);
      puts("");
    }
    if (op[0] == 'i') {
      scanf("%d", &x);
      Insert(Root, NIL, x);
    }
    if (op[0] == 'f') {
      scanf("%d", &x);
      node *p = Find(Root, x);
      if (p == NIL)
        puts("no");
      else
        puts("yes");
    }
    if (op[0] == 'd') {
      scanf("%d", &x);
      Delete(Root, x);
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
#define ms(a) memset(a, 0, sizeof(a))
#define inf 0x3f3f3f3f
#define MAX 100010
#define MX 10010
#define ll long long
using namespace std;
struct node {
  int data;
  node *lch, *rch, *par;
} *root, *null;
void insert(int k) {
  node *cur = root, *res = null, *ins = (node *)malloc(sizeof(node));
  ins->data = k;
  ins->lch = null;
  ins->rch = null;
  while (cur != null) {
    res = cur;
    if (ins->data < cur->data)
      cur = cur->lch;
    else
      cur = cur->rch;
  }
  ins->par = res; // 定?父?点
  if (res == null)
    root = ins; // 第一次插入
  else {        // 定?左右子
    if (ins->data < res->data)
      res->lch = ins;
    else
      res->rch = ins;
  }
}
bool find(int k) {
  node *cur = root;
  while (cur != null) {
    if (k < cur->data)
      cur = cur->lch;
    else if (k > cur->data)
      cur = cur->rch;
    else
      return 1;
  }
  return 0;
}
void dele(node *cur) //?除非双子?点
{
  node *p, *l, *r;
  p = cur->par;
  l = cur->lch;
  r = cur->rch;
  if (l == null && r == null) { // 叶子?点
    if (cur == root)
      root = null;
    else if (cur == p->lch)
      p->lch = null;
    else
      p->rch = null;
  } else if (l == null) { // 只有右子
    if (cur == root)
      root = r;
    else if (cur == p->lch)
      p->lch = r;
    else
      p->rch = r;
    r->par = p;
  } else if (r == null) { // 只有左子
    if (cur == root)
      root = l;
    else if (cur == p->lch)
      p->lch = l;
    else
      p->rch = l;
    l->par = p;
  }
}
void delet(int k) //?除?个?点
{
  node *cur = root, *p, *l, *r;
  while (cur != null) {
    if (k < cur->data)
      cur = cur->lch;
    else if (k > cur->data)
      cur = cur->rch;
    else
      break;
  }
  if (cur == null)
    return;
  p = cur->par;
  l = cur->lch;
  r = cur->rch;
  if (l != null && r != null) { // 双子?点
    node *cu = r, *next = null; // 中序遍?的下一个?点
    while (cu != null) {
      next = cu;
      cu = cu->lch;
    }
    dele(next); // 先?接next上下
    // 再?接cur上下
    l->par = next;
    next->lch = l;
    r->par = next;
    next->rch = r;
    if (cur == root)
      root = next; // 若?除?根?点，需替?
    else if (cur == p->lch)
      p->lch = next;
    else
      p->rch = next;
    next->par = p;
  } else
    dele(cur);
}
void inorder(node *cur) {
  if (cur == null)
    return;
  inorder(cur->lch);
  printf(" %d", cur->data);
  inorder(cur->rch);
}
void preorder(node *cur) {
  if (cur == null)
    return;
  printf(" %d", cur->data);
  preorder(cur->lch);
  preorder(cur->rch);
}
int main() {
  int n, m;
  char oper[10];
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", &oper);
    if (oper[0] == 'i') {
      scanf("%d", &m);
      insert(m);
    } else if (oper[0] == 'f') {
      scanf("%d", &m);
      printf("%s\\n", find(m) ? "yes" : "no");
    } else if (oper[0] == 'd') {
      scanf("%d", &m);
      delet(m);
    } else if (oper[0] == 'p') {
      inorder(root);
      printf("\\n");
      preorder(root);
      printf("\\n");
    }
  }
  return 0;
}