#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

struct TreeNode {
  int val;
  struct TreeNode *left;
  struct TreeNode *right;
};

struct list_t {
  int *data;
  size_t cur;
  size_t size;
};

struct list_t *init_list() {
  struct list_t *list = (struct list_t *)malloc(sizeof(struct list_t));
  list->data = (int *)malloc(sizeof(int) * 10);
  list->cur = 0;
  list->size = 10;

  return list;
}

void append(struct list_t *list, int v) {
  if (list->cur == list->size) {
    list->data = realloc(list->data, sizeof(int) * (list->size + 10));
    list->size += 10;
  }
  list->data[list->cur] = v;
  list->cur++;
}

void delete(struct list_t *list) {
  if (!list)
    return;

  free(list->data);
  free(list);
  list = NULL;
}

bool cmp(struct list_t *a, struct list_t *b) {
  if (a->cur != b->cur)
    return false;
  for (int i = 0; i < a->size; i++)
    if (a->data[i] != b->data[i])
      return false;
  return true;
}

void post(struct TreeNode *node, struct list_t *list) {
  if (!node) {
    append(list, INT_MIN);
    return;
  }
  append(list, node->val);
  post(node->left, list);
  post(node->right, list);
}

bool isSameTree(struct TreeNode *p, struct TreeNode *q) {
  struct list_t *pl = init_list();
  struct list_t *ql = init_list();

  post(p, pl);
  post(q, ql);

  bool ret = cmp(pl, ql);

  delete (pl);
  delete (ql);

  return ret;
}

int main() {
  struct TreeNode t1 = {1, 0, 0};
  struct TreeNode t2 = {2, 0, 0};
  struct TreeNode t3 = {3, 0, 0};
  struct TreeNode t4 = {1, 0, 0};
  struct TreeNode t5 = {2, 0, 0};
  struct TreeNode t6 = {3, 0, 0};

  t1.left = &t2;
  t2.left = &t3;

  t4.right = &t5;
  t5.right = &t6;

  assert(isSameTree(&t1, &t2) == false);
  assert(isSameTree(&t1, &t4) == false);
  assert(isSameTree(&t1, &t1) == true);

  return 0;
}
