1. 程式人生 > >【面試算法系列】已知二叉樹的前序和中序遍歷重建二叉樹

【面試算法系列】已知二叉樹的前序和中序遍歷重建二叉樹

已知一二叉樹的前序遍歷和中序遍歷重建二叉樹

1. 輸入前序遍歷陣列和中序遍歷陣列

2. 由前序遍歷順序可得,第一個節點是該二叉樹的根節點。

3. 在中序遍歷中尋找該根節點位置,該節點左邊是它的左子樹上的節點,右邊節點是它右子樹上的節點。

4. 獲取該節點左邊的節點數n,前序遍歷除了首節點以外的前n個節點為左子樹節點,後邊剩下的節點為右子樹上的節點。

5. 以中序遍歷的根節點為分界,分為兩個陣列,左邊重複第一步,右邊也重複第一步,直到只有一個節點,則返回這個節點。

/* 
 * File:   main.c
 * Author: Kyle
 *
 * Created on 2015年9月7日, 下午2:34
 */

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

typedef int Item; //定義資料項型別  
/*
 *二叉樹,結構體
 */
typedef struct btn {
    Item value; //資料域  
    struct btn* L; //左子節點  
    struct btn* R; //右子節點 
} BinaryTreeNode;

BinaryTreeNode* makeTree(int* a_start, int* a_end, int* b_start, int* b_end) {
    //    printf("R:  %d,%d,%d,%d\n", *a_start, *a_end, *b_start, *b_end);
    BinaryTreeNode *RootNode = (BinaryTreeNode *) malloc(sizeof (BinaryTreeNode));
    RootNode->value = *a_start;
    RootNode->L = NULL;
    RootNode->R = NULL;
    if (*a_start == *a_end) {//當中序跟前序一樣的時候返回該節點,說明已經判斷到了最後一個點
        return RootNode;
    }
    int *i = b_start; //中序中找首節點
    int leftLength = 0; //左子樹的個數
    while (*a_start != *i) {
        ++i;
        //        printf("%d\n",*a_start);
        ++leftLength;
    }
    if (leftLength > 0) {
        RootNode->L = makeTree(a_start + 1, a_start + leftLength, b_start, b_start + leftLength - 1);
        printf("L:  %d,%d,%d,%d-----%d\n", *(a_start + 1), *(a_start + leftLength), *(b_start), *(b_start + leftLength - 1), leftLength);
    }
    if (i != b_end) {
        RootNode->R = makeTree(a_start + leftLength + 1, a_end, i + 1, b_end);
        printf("R:  %d,%d,%d,%d-----%d\n", *(a_start + leftLength + 1), *a_end, *(i + 1), *b_end);
    }
    return RootNode;
}

BinaryTreeNode* Construct(int* a, int a_length, int* b, int b_length) {
    if (a == NULL || b == NULL || a_length < 0 || b_length < 0) {
        printf("NULLl");
        return NULL;
    } else {
        return makeTree(a, a + a_length - 1, b, b + b_length - 1);
    }
}

int main() {

            /**  ab分別為如下二叉樹的前序遍歷和中序遍歷
                          1
             *           / \
             *          2   3
             *         /   / \
             *        4   5   6
             *         \     /
             *          7   8
             **/
            int a[] = {1, 2, 4, 7, 3, 5, 6, 8};
            int b[] = {4, 7, 2, 1, 5, 3, 8, 6};
            BinaryTreeNode *result = Construct(a, 8, b, 8);
            printf("%d\n", result->L->value);
            printf("%d\n", result->R->value);
            printf("%d\n", result->L->L->value);
            printf("%d\n", result->L->L->R->value);
            printf("%d\n", result->R->L->value);
            printf("%d\n", result->R->R->value);
            printf("%d\n", result->R->R->L->value);
    return (EXIT_SUCCESS);
}