1044. Shopping in Mars (25)解题报告

本文介绍了一种根据给定的中序遍历和前序遍历序列重构二叉搜索树的方法,并实现了两种不同的重构策略。通过使用递归算法,程序能够正确地构建出原始的二叉树结构,并进行后序遍历输出。此外,还提供了清理内存以避免内存泄漏的函数。
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <iostream>


struct node {
    int data;
    struct node *left, *right, *parent;
};

node *rebuild1(int left1, int right1, int left2, int right2);
node *rebuild2(int left1, int right1, int left2, int right2);
void posttraversal(node *root);
void deletree(node *root);
int cmp1(const void *v1, const void *v2) {
    return *((int *)v1) - *((int *)v2);
}
int cmp2(const void *v1, const void *v2) {
    return *((int *)v2) - *((int *)v1);
}
int find1(int aim, int arr[], int begin, int end) {
    int i;
    i = begin;
    while (i <= end) {
        if (arr[i] == aim) {
            return i;
        }
        i++;
    }
    return -1;
}
int find2(int aim, int arr[], int begin, int end) {
    int i;
    i = end;
    while (i >= begin) {
        if (arr[i] == aim) {
            return i;
        }
        i--;
    }
    return -1;
}

int arr1[1000], arr2[1000], arr3[1000];
bool flag1 = true, flag2 = true;
int main(void) {
    int n, i;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%d", arr1 + i);
        arr2[i] = arr3[i] = arr1[i];
    }
    qsort(arr2, n, sizeof(int), cmp1);
    qsort(arr3, n, sizeof(int), cmp2);

    node *root1, *root2;
    root1 = rebuild1(0, n - 1, 0, n - 1);
    root2 = rebuild2(0, n - 1, 0, n - 1);
    if (flag1) {
        puts("YES");
        posttraversal(root1->left);
        posttraversal(root1->right);
        printf("%d\n", root1->data);
    }
    else if (flag2) {
        puts("YES");
        posttraversal(root2->left);
        posttraversal(root2->right);
        printf("%d\n", root2->data);
    }
    else {
        puts("NO");
    }
    deletree(root1);
    deletree(root2);
    return 0;
}

node *rebuild1(int left1, int right1, int left2, int right2) {
    if (left1 > right1) {
        return nullptr;
    }
    else if (left1 == right1) {
        if (arr1[left1] != arr2[left2] || right2 != left2) {
            flag1 = false;
            return nullptr;
        }
        node *tmp = new node;
        tmp->data = arr1[left1];
        tmp->left = nullptr;
        tmp->right = nullptr;
        return tmp;
    }
    else if (right1 - left1 == right2 - left2) {
        node *tmp = new node;
        tmp->data = arr1[left1];
        int index = find1(arr1[left1], arr2, left2, right2);
        if (index == -1) {
            flag1 = false;
            return nullptr;
        }
        tmp->left = rebuild1(left1 + 1, left1 + index - left2, left2, index - 1);
        tmp->right = rebuild1(left1 + index - left2 + 1, right1, index + 1, right2);
        return tmp;
    }
    else {
        flag1 = false;
        return nullptr;
    }
}

node *rebuild2(int left1, int right1, int left2, int right2) {
    if (left1 > right1) {
        return nullptr;
    }
    else if (left1 == right1) {
        if (arr1[left1] != arr3[left2] || right2 != left2) {
            flag2 = false;
            return nullptr;
        }
        node *tmp = new node;
        tmp->data = arr1[left1];
        tmp->left = nullptr;
        tmp->right = nullptr;
        return tmp;
    }
    else if (right1 - left1 == right2 - left2) {
        node *tmp = new node;
        tmp->data = arr1[left1];
        int index = find2(arr1[left1], arr3, left2, right2);
        if (index == -1) {
            flag2 = false;
            return nullptr;
        }
        tmp->left = rebuild2(left1 + 1, left1 + index - left2, left2, index - 1);
        tmp->right = rebuild2(left1 + index - left2 + 1, right1, index + 1, right2);
        return tmp;
    }
    else {
        flag2 = false;
        return nullptr;
    }
}
void posttraversal(node *root) {
    if (!root) {
        return;
    }
    else {
        posttraversal(root->left);
        posttraversal(root->right);
        printf("%d ", root->data);
        return;
    }
}
void deletree(node *root) {
    if (!root) {
        return;
    }
    else {
        deletree(root->left);
        deletree(root->right);
        free(root);
        return;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值