Problem p02282 (C++)

Buggy submission (status: Runtime Error):
#include <cstdlib>
#include <iostream>
#include <list>

const int MAX_N = 25;
const int SINGLE_NODE = 1;
const int NONE = -1;

struct Node {
  int parent;
  int left;
  int right;
  bool visited;
};

int reconstruct(std::list<int> *preorderNodes, std::list<int> *inorderNodes,
                int parent, struct Node *nodes[]) {
  if (inorderNodes->size() == SINGLE_NODE) {
    int v = inorderNodes->front();
    inorderNodes->pop_front();

    nodes[v]->parent = parent;

    preorderNodes->pop_front();

    return v;
  }

  int v = preorderNodes->front();
  preorderNodes->pop_front();

  std::list<int> *leftNodes = new std::list<int>();
  std::list<int> *rightNodes = new std::list<int>();

  while (!inorderNodes->empty()) {
    int k = inorderNodes->front();
    inorderNodes->pop_front();

    if (k == v) {
      break;
    } else {
      leftNodes->push_back(k);
    }
  }

  while (!inorderNodes->empty()) {
    int k = inorderNodes->front();
    inorderNodes->pop_front();

    //    if (k == v) {
    //      break;
    //    } else {
    rightNodes->push_back(k);
    //    }
  }

  //  std::cout << v << std::endl;

  if (!leftNodes->empty()) {
    // std::cout << "Left: ";

    // for (std::list<int>::iterator i = leftNodes->begin(); i !=
    // leftNodes->end(); ++i) {
    //   std::cout << (*i) << " ";
    // }

    // std::cout << std::endl;

    nodes[v]->left = reconstruct(preorderNodes, leftNodes, v, nodes);
  }

  if (!rightNodes->empty()) {
    // std::cout << "Right: ";

    // for (std::list<int>::iterator i = rightNodes->begin(); i !=
    // rightNodes->end(); ++i) {
    //   std::cout << (*i) << " ";
    // }

    // std::cout << std::endl;

    nodes[v]->right = reconstruct(preorderNodes, rightNodes, v, nodes);
  }

  nodes[v]->parent = parent;

  return v;
}

void printByPostorder(struct Node *nodes[], int n, int rootID) {
  std::list<int> list;

  list.push_front(rootID);

  bool first = true;

  while (!list.empty()) {
    int id = list.front();
    list.pop_front();

    if (id < 0) {
      continue;
    }

    struct Node *node = nodes[id];

    if (!node->visited) {
      node->visited = true;

      list.push_front(id);
      list.push_front(node->right);
      list.push_front(node->left);
    } else {
      if (first) {
        std::cout << id;

        first = false;
      } else {
        std::cout << " " << id;
      }
    }
  }

  std::cout << std::endl;
}

int main(void) {
  int n;

  std::cin >> n;

  struct Node *nodes[MAX_N];

  for (int i = 0; i <= n; i++) {
    struct Node *node = (struct Node *)std::malloc(sizeof(struct Node));

    node->parent = NONE;
    node->left = NONE;
    node->right = NONE;
    node->visited = false;

    nodes[i] = node;
  }

  std::list<int> *preorderNodes = new std::list<int>();
  std::list<int> *inorderNodes = new std::list<int>();

  for (int i = 0; i < n; i++) {
    int v = 0;

    std::cin >> v;

    preorderNodes->push_back(v);
  }

  for (int i = 0; i < n; i++) {
    int v = 0;

    std::cin >> v;

    inorderNodes->push_back(v);
  }

  int rootID = preorderNodes->front();

  reconstruct(preorderNodes, inorderNodes, -1, nodes);

  printByPostorder(nodes, n, rootID);

  return 0;
}

Fixed submission:
#include <cstdlib>
#include <iostream>
#include <list>

const int MAX_N = 41;
const int SINGLE_NODE = 1;
const int NONE = -1;

struct Node {
  int parent;
  int left;
  int right;
  bool visited;
};

int reconstruct(std::list<int> *preorderNodes, std::list<int> *inorderNodes,
                int parent, struct Node *nodes[]) {
  if (inorderNodes->size() == SINGLE_NODE) {
    int v = inorderNodes->front();
    inorderNodes->pop_front();

    nodes[v]->parent = parent;

    preorderNodes->pop_front();

    return v;
  }

  int v = preorderNodes->front();
  preorderNodes->pop_front();

  std::list<int> *leftNodes = new std::list<int>();
  std::list<int> *rightNodes = new std::list<int>();

  while (!inorderNodes->empty()) {
    int k = inorderNodes->front();
    inorderNodes->pop_front();

    if (k == v) {
      break;
    } else {
      leftNodes->push_back(k);
    }
  }

  while (!inorderNodes->empty()) {
    int k = inorderNodes->front();
    inorderNodes->pop_front();

    //    if (k == v) {
    //      break;
    //    } else {
    rightNodes->push_back(k);
    //    }
  }

  //  std::cout << v << std::endl;

  if (!leftNodes->empty()) {
    // std::cout << "Left: ";

    // for (std::list<int>::iterator i = leftNodes->begin(); i !=
    // leftNodes->end(); ++i) {
    //   std::cout << (*i) << " ";
    // }

    // std::cout << std::endl;

    nodes[v]->left = reconstruct(preorderNodes, leftNodes, v, nodes);
  }

  if (!rightNodes->empty()) {
    // std::cout << "Right: ";

    // for (std::list<int>::iterator i = rightNodes->begin(); i !=
    // rightNodes->end(); ++i) {
    //   std::cout << (*i) << " ";
    // }

    // std::cout << std::endl;

    nodes[v]->right = reconstruct(preorderNodes, rightNodes, v, nodes);
  }

  nodes[v]->parent = parent;

  return v;
}

void printByPostorder(struct Node *nodes[], int n, int rootID) {
  std::list<int> list;

  list.push_front(rootID);

  bool first = true;

  while (!list.empty()) {
    int id = list.front();
    list.pop_front();

    if (id < 0) {
      continue;
    }

    struct Node *node = nodes[id];

    if (!node->visited) {
      node->visited = true;

      list.push_front(id);
      list.push_front(node->right);
      list.push_front(node->left);
    } else {
      if (first) {
        std::cout << id;

        first = false;
      } else {
        std::cout << " " << id;
      }
    }
  }

  std::cout << std::endl;
}

int main(void) {
  int n;

  std::cin >> n;

  struct Node *nodes[MAX_N];

  for (int i = 0; i <= n; i++) {
    struct Node *node = (struct Node *)std::malloc(sizeof(struct Node));

    node->parent = NONE;
    node->left = NONE;
    node->right = NONE;
    node->visited = false;

    nodes[i] = node;
  }

  std::list<int> *preorderNodes = new std::list<int>();
  std::list<int> *inorderNodes = new std::list<int>();

  for (int i = 0; i < n; i++) {
    int v = 0;

    std::cin >> v;

    preorderNodes->push_back(v);
  }

  for (int i = 0; i < n; i++) {
    int v = 0;

    std::cin >> v;

    inorderNodes->push_back(v);
  }

  int rootID = preorderNodes->front();

  reconstruct(preorderNodes, inorderNodes, -1, nodes);

  printByPostorder(nodes, n, rootID);

  return 0;
}