#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Node structure for binary tree
struct Node {
    char data;
    struct Node *left, *right;
};

// Stack structure for tree construction
struct Stack {
    struct Node **array;
    int top;
    int capacity;
};

// Function to create a new node
struct Node* newNode(char data) {
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = data;
    node->left = node->right = NULL;
    return node;
}

// Stack operations
struct Stack* createStack(int capacity) {
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->capacity = capacity;
    stack->top = -1;
    stack->array = (struct Node**)malloc(stack->capacity * sizeof(struct Node*));
    return stack;
}

void push(struct Stack* stack, struct Node* item) {
    stack->array[++stack->top] = item;
}

struct Node* pop(struct Stack* stack) {
    if (stack->top == -1) return NULL;
    return stack->array[stack->top--];
}

// Search for index in inorder array
int search(char arr[], char x, int n) {
    for (int i = 0; i < n; i++)
        if (arr[i] == x)
            return i;
    return -1;
}

// Build tree from given inorder and preorder traversals
struct Node* buildTree(char inorder[], char preorder[], int inStart, int inEnd, int* preIndex, int n) {
    if (inStart > inEnd) return NULL;

    struct Node* node = newNode(preorder[*preIndex]);
    (*preIndex)++;

    if (inStart == inEnd) return node;

    int inIndex = search(inorder, node->data, n);

    node->left = buildTree(inorder, preorder, inStart, inIndex-1, preIndex, n);
    node->right = buildTree(inorder, preorder, inIndex+1, inEnd, preIndex, n);

    return node;
}

// Different traversal functions
void printPreorder(struct Node* node) {
    if (node == NULL) return;
    printf("%c ", node->data);
    printPreorder(node->left);
    printPreorder(node->right);
}

void printInorder(struct Node* node) {
    if (node == NULL) return;
    printInorder(node->left);
    printf("%c ", node->data);
    printInorder(node->right);
}

void printPostorder(struct Node* node) {
    if (node == NULL) return;
    printPostorder(node->left);
    printPostorder(node->right);
    printf("%c ", node->data);
}

// Convert between different traversals
void convertTraversal(char input[], char type1[], char type2[], int n) {
    // Create arrays to store traversals
    char inorder[100], preorder[100];
    int preIndex = 0;

    // If input is preorder, use it directly
    if (strcmp(type1, "preorder") == 0) {
        strcpy(preorder, input);
        strcpy(inorder, type2);
    }
    // If input is inorder, use it with preorder
    else if (strcmp(type1, "inorder") == 0) {
        strcpy(inorder, input);
        strcpy(preorder, type2);
    }

    // Build tree from traversals
    struct Node* root = buildTree(inorder, preorder, 0, n-1, &preIndex, n);

    // Print requested traversal
    printf("\nConverted traversal: ");
    if (strcmp(type2, "preorder") == 0)
        printPreorder(root);
    else if (strcmp(type2, "inorder") == 0)
        printInorder(root);
    else if (strcmp(type2, "postorder") == 0)
        printPostorder(root);
}

int main() {
    // Example usage
    char input[] = "DBEAFC"; // Input traversal
    char type1[] = "preorder"; // Type of input traversal
    char type2[] = "postorder"; // Required output traversal
    int n = strlen(input);

    printf("Input %s traversal: %s\n", type1, input);
    convertTraversal(input, type1, type2, n);

    return 0;
}
