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

// 木の巡回
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>

using namespace std;

#define MAX_N 30
const int NIL = -1;

typedef struct node {
  // 節点の親
  int parent;
  // 節点の左の子
  int left;
  // 節点の右の子
  int right;
} Node;

// グローバル変数の定義
Node Tree[MAX_N];
int treeWalk[MAX_N];
int n, elementNum;

void print(int num);
void preorderTreeWalk(int ele_num);
void inorderTreeWalk(int ele_num);
void postorderTreeWalk(int ele_num);

int main(void) {

  int i, node, left, right, root;

  cin >> n;

  for (i = 0; i < n; i++) {
    // 全要素の初期化
    Tree[i].parent = NIL;
    Tree[i].left = NIL;
    Tree[i].right = NIL;
  }

  for (i = 0; i < n; i++) {
    cin >> node >> left >> right;

    // 左の子を設定する
    Tree[node].left = left;
    // 右の子を設定する
    Tree[node].right = right;

    // 親の情報を設定
    if (left != NIL) {
      Tree[left].parent = node;
    }

    if (right != NIL) {
      Tree[right].parent = node;
    }
  }

  for (i = 0; i < n; i++) {
    if (Tree[i].parent == NIL) {
      // ルートの要素を検索する
      // [ 親 = NIL ] のものが, rootとなる
      root = i;
    }
  }

  elementNum = 0;
  preorderTreeWalk(root);
  print(1);

  elementNum = 0;
  inorderTreeWalk(root);
  print(2);

  elementNum = 0;
  postorderTreeWalk(root);
  print(3);

  return 0;
}

// 結果の表示用
void print(int num) {
  switch (num) {
  case 1:
    printf("Preorder\\n");
    break;

  case 2:
    printf("Inorder\\n");
    break;

  case 3:
    printf("Postorder\\n");
    break;
  }

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

    printf("%d", treeWalk[i]);
  }

  printf("\\n");
}

// 根節点、左部分木、右部分木の順で節点を巡回
void preorderTreeWalk(int ele_num) {
  if (ele_num == NIL) {
    return;
  }

  treeWalk[elementNum++] = ele_num;
  preorderTreeWalk(Tree[ele_num].left);
  preorderTreeWalk(Tree[ele_num].right);

  return;
}

int pre_right = 0;

// 左部分木、根節点、右部分木の順で節点を巡回
void inorderTreeWalk(int ele_num) {

  if (ele_num == NIL) {
    return;
  }

  inorderTreeWalk(Tree[ele_num].left);
  treeWalk[elementNum++] = ele_num;
  inorderTreeWalk(Tree[ele_num].right);

  return;
}

// 左部分木、右部分木、根節点の順で節点を巡回
void postorderTreeWalk(int ele_num) {

  if (ele_num == NIL) {
    return;
  }

  postorderTreeWalk(Tree[ele_num].left);
  postorderTreeWalk(Tree[ele_num].right);
  treeWalk[elementNum++] = ele_num;

  return;
}


Error: -11

Fixed submission:

// 木の巡回
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>

using namespace std;

#define MAX_N 30
const int NIL = -1;
const int PASS = -10;

typedef struct node {
  // 節点の親
  int parent;
  // 節点の左の子
  int left;
  // 節点の右の子
  int right;
} Node;

// グローバル変数の定義
Node Tree[MAX_N];
int treeWalk[MAX_N];
int n, elementNum;

void print(void);
void preorderTreeWalk(int ele_num);
void inorderTreeWalk(int ele_num);
void postorderTreeWalk(int ele_num);

int main(void) {

  int i, node, left, right, root;

  cin >> n;

  for (i = 0; i < n; i++) {
    // 全要素の初期化
    Tree[i].parent = NIL;
    Tree[i].left = NIL;
    Tree[i].right = NIL;
  }

  for (i = 0; i < n; i++) {
    cin >> node >> left >> right;

    // 左の子を設定する
    Tree[node].left = left;
    // 右の子を設定する
    Tree[node].right = right;

    // 親の情報を設定
    if (left != NIL) {
      Tree[left].parent = node;
    }

    if (right != NIL) {
      Tree[right].parent = node;
    }
  }

  for (i = 0; i < n; i++) {
    if (Tree[i].parent == NIL) {
      // ルートの要素を検索する
      // [ 親 = NIL ] のものが, rootとなる
      root = i;
    }
  }

  elementNum = 0;
  preorderTreeWalk(root);
  print();

  elementNum = 0;
  inorderTreeWalk(root);
  print();

  elementNum = 0;
  postorderTreeWalk(root);
  print();

  return 0;
}

// 結果の表示用
void print(void) {
  for (int i = 0; i < n; i++) {
    if (i)
      printf(" ");

    printf("%d", treeWalk[i]);
  }

  printf("\\n");
}

// 根節点、左部分木、右部分木の順で節点を巡回
void preorderTreeWalk(int ele_num) {
  if (elementNum == n) {
    return;
  }

  if (elementNum == 0) {
    // 根
    treeWalk[elementNum++] = ele_num;
  }

  if (Tree[ele_num].left != NIL) {
    // 左部分木
    treeWalk[elementNum++] = Tree[ele_num].left;
    preorderTreeWalk(Tree[ele_num].left);
  }

  if (Tree[ele_num].right != NIL) {
    // 右部分木
    treeWalk[elementNum++] = Tree[ele_num].right;
    preorderTreeWalk(Tree[ele_num].right);
  }

  return;
}

// 左部分木、根節点、右部分木の順で節点を巡回
void inorderTreeWalk(int ele_num) {

  int parent;
  if (elementNum == n) {
    return;
  }

  if (Tree[ele_num].left == NIL) {
    // まだ, 通過していない点の場合に処理する

    parent = Tree[ele_num].parent;

    treeWalk[elementNum++] = Tree[parent].left;  // 左
    treeWalk[elementNum++] = parent;             // 真ん中
    treeWalk[elementNum++] = Tree[parent].right; // 右

    // 表示した点は通過した通知を入れる
    Tree[parent].left = PASS;
    // Tree[ele_num].parent = NIL;
    Tree[parent].right = PASS;

    // 親の親の左の子は, 上の Tree[parent].left である
    Tree[Tree[parent].parent].left = PASS;

    // 親の親を設定して, 一つ上がる
    inorderTreeWalk(Tree[parent].parent);
  } else {
    if (Tree[ele_num].left > NIL) {
      // 左部分木
      inorderTreeWalk(Tree[ele_num].left);
    }
  }

  if (Tree[ele_num].right != NIL) {
    if (elementNum != 0 && Tree[ele_num].parent == NIL) {
      // 根
      treeWalk[elementNum++] = ele_num;
    }

    // 右部分木
    inorderTreeWalk(Tree[ele_num].right);

    if (Tree[ele_num].left == PASS) {
      treeWalk[elementNum++] = Tree[ele_num].right;
    }
  }

  return;
}

// 左部分木、右部分木、根節点の順で節点を巡回
void postorderTreeWalk(int ele_num) { return; }