Problem p02285 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
struct node {
  struct node *parent, *left, *right;
  int key;
};
node NIL;
node *nil = &NIL;
node *root = nil;
void setdepth(node *, int);
node *getroot(node *);
void inorder(node *);
void preorder(node *);
void insert(int);
void print();
node *find(int);
void deletenode(node *);
node *getnext(node *);
char isleft(node *);

int main() {
  int n;
  cin >> n;
  nil->parent = nil->left = nil->right = nil;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    if (s == "insert") {
      int key;
      cin >> key;
      insert(key);
    } else if (s == "print")
      print();
    else if (s == "find") {
      int key;
      cin >> key;
      if (find(key) != nil)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    } else if (s == "delete") {
      int key;
      cin >> key;
      deletenode(find(key));
    }
  }

  return 0;
}

node *getroot(node *x) {
  int i = 0;
  while (x->parent != nil) {
    x = x->parent;
    i++;
    if (i >= 100000) {
      // cerr << "ERROR:GETROOT" << endl;
      break;
    }
  }
  ////cerr << "root: " << x->key<< endl;
  return x;
}

void printchildren(node *x) {}

void insert(int key) {
  node *x;
  x = (node *)malloc(sizeof(node));
  x->key = key;
  x->parent = x->left = x->right = nil;
  if (root == nil)
    root = x;
  else {
    node *cur = root;
    node *prev = cur;
    bool isleft = true;
    while (cur != nil) {
      prev = cur;
      if (key <= cur->key) {
        isleft = true;
        cur = cur->left;
      } else {
        cur = cur->right;
        isleft = false;
      }
    }
    x->parent = prev;
    if (isleft)
      prev->left = x;
    else
      prev->right = x;
  }
}

void inorder(node *x) {
  if (x->left != nil)
    inorder(x->left);
  cout << " " << x->key;
  if (x->right != nil)
    inorder(x->right);
}

void preorder(node *x) {
  if (x == nil)
    return;
  else {
    cout << " " << x->key;
    preorder(x->left);
    preorder(x->right);
  }
}

void print() {
  inorder(root);
  cout << endl;
  preorder(root);
  cout << endl;
}

node *find(int key) {
  node *x = root;
  while (x != nil && x->key != key) {
    if (key < x->key)
      x = x->left;
    else
      x = x->right;
  }
  return x;
}

void deletenode(node *x) {
  if (x == nil)
    return;
  assert(x != nil);
  if (x->left != nil && x->right != nil) {
    node *y = getnext(x);
    assert(x != y);
    // cerr << "next of " <<x->key <<": " << y->key <<endl;
    assert(y != nil);
    x->key = y->key;
    deletenode(y);
  } else if (x->left == nil && x->right == nil) {
    if (isleft(x) == 'L')
      x->parent->left = nil;
    else
      x->parent->right = nil;
    free(x);
  } else {
    node *child;
    if (x->left != nil)
      child = x->left;
    else
      child = x->right;

    if (isleft(x) == 'L') {
      x->parent->left = child;
      child->parent = x->parent;
      free(x);
    } else if (isleft(x) == 'R') {
      x->parent->right = child;
      child->parent = x->parent;
      free(x);
    } else if (isleft(x) == 'N') {
      child->parent = nil;
      root = child;
      free(x);
    }
  }
}

char isleft(node *x) {
  assert(x != nil);
  if (x->parent == nil)
    return 'N';
  else if (x->parent->left == x)
    return 'L';
  else
    return 'R';
}

node *getnext(node *x) {
  if (x->right == nil) {
    while (isleft(x) == 'L') {
      if (isleft(x) == 'N')
        return nil;
      x = x->parent;
    }
    return x->parent;
  } else {
    x = x->right;
    while (x->left != nil) {
      x = x->left;
    }
    // cerr <<"getnext :" << x->key <<endl;
    return x;
  }
}

Error: TLE

Fixed submission:

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
struct node {
  struct node *parent, *left, *right;
  int key;
};
node NIL;
node *nil = &NIL;
node *root = nil;
void setdepth(node *, int);
node *getroot(node *);
void inorder(node *);
void preorder(node *);
void insert(int);
void print();
node *find(int);
void deletenode(node *);
node *getnext(node *);
char isleft(node *);

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    if (s == "insert") {
      int key;
      cin >> key;
      insert(key);
    } else if (s == "print")
      print();
    else if (s == "find") {
      int key;
      cin >> key;
      if (find(key) != nil)
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    } else if (s == "delete") {
      int key;
      cin >> key;
      deletenode(find(key));
    }
  }

  return 0;
}

node *getroot(node *x) {
  int i = 0;
  while (x->parent != nil) {
    x = x->parent;
    i++;
    if (i >= 100000) {
      cerr << "ERROR:GETROOT" << endl;
      break;
    }
  }
  // cerr << "root: " << x->key<< endl;
  return x;
}

void printchildren(node *x) {}

void insert(int key) {
  node *x;
  x = (node *)malloc(sizeof(node));
  x->key = key;
  x->parent = x->left = x->right = nil;
  if (root == nil)
    root = x;
  else {
    node *cur = root;
    node *prev = cur;
    bool isleft = true;
    while (cur != nil) {
      prev = cur;
      if (key <= cur->key) {
        isleft = true;
        cur = cur->left;
      } else {
        cur = cur->right;
        isleft = false;
      }
    }
    x->parent = prev;
    if (isleft)
      prev->left = x;
    else
      prev->right = x;
  }
}

void inorder(node *x) {
  if (x->left != nil)
    inorder(x->left);
  cout << " " << x->key;
  if (x->right != nil)
    inorder(x->right);
}

void preorder(node *x) {
  if (x == nil)
    return;
  else {
    cout << " " << x->key;
    preorder(x->left);
    preorder(x->right);
  }
}

void print() {
  inorder(root);
  cout << endl;
  preorder(root);
  cout << endl;
}

node *find(int key) {
  node *x = root;
  while (x != nil && x->key != key) {
    if (key < x->key)
      x = x->left;
    else
      x = x->right;
  }
  return x;
}

void deletenode(node *x) {
  if (x == nil)
    return;
  assert(x != nil);
  if (x->left != nil && x->right != nil) {
    node *y = getnext(x);
    assert(y != nil);
    x->key = y->key;
    deletenode(y);
  } else if (x->left == nil && x->right == nil) {
    if (isleft(x) == 'L')
      x->parent->left = nil;
    else
      x->parent->right = nil;
    free(x);
  } else {
    node *child;
    if (x->left != nil)
      child = x->left;
    else
      child = x->right;

    if (isleft(x) == 'L') {
      x->parent->left = child;
      child->parent = x->parent;
      free(x);
    } else if (isleft(x) == 'R') {
      x->parent->right = child;
      child->parent = x->parent;
      free(x);
    } else if (isleft(x) == 'N') {
      child->parent = nil;
      free(x);
    }
  }
}

char isleft(node *x) {
  assert(x != nil);
  if (x->parent == nil)
    return 'N';
  else if (x->parent->left == x)
    return 'L';
  else
    return 'R';
}

node *getnext(node *x) {
  if (x->right == nil) {
    while (isleft(x) == 'L') {
      if (isleft(x) == 'N')
        return nil;
      x = x->parent;
    }
    return x->parent;
  } else {
    while (x->right == nil) {
      x = x->right;
    }
    return x;
  }
}