讓我們考慮以下遍歷結果:
中序序列:DBEAFC
前序序列:ABDECF
在前序序列中, 最左邊的元素是樹的根。對於上面給定的序列,我們知道 ‘A’ 是樹的根。
然后在中序序列中找到 ‘A’ 的位置,我們發現所有位於 ‘A’ 左邊的元素存在於樹的左子樹,
位於 ‘A’ 右邊的元素存在於樹的右子樹。
A / \ / \ D B E F C
我們遞歸地按照上述步驟來構建整棵樹。
A / \ / \ B C / \ / / \ / D E F
Algorithm
定義函數 buildTree()
- 在前序序列中取出一個元素。增加前序序列索引變量,以便在下次遞歸調用過程中取下一個元素。
- 用取出元素作為數據域創建一個新節點 tNode。
- 在中序序列中查找取出元素的索引,賦值給 inIndex。
- 用 inIndex 之前的元素遞歸調用 buildTree()創建樹,並將其作為 tNode 的左子樹。
- 用 inIndex 之前的元素遞歸調用 buildTree()創建樹,並將其作為 tNode 的右子樹。
- 返回 tNode
#include <stdio.h> #include <stdlib.h> /*
* 一個二叉樹結點包括數據域,和指向左子樹與右子樹的指針
*/ struct node { char data; struct node* left; struct node* right; }; int search(char arr[], int strt, int end, char value); struct node* newNode(char data);
/*
* 前序序列索引
*/
int preIndex = 0;
/*
* 利用中序序列 in[] 和前序序列 pre[] 遞歸地構造一棵大小為 len 的二叉樹
* inStart 和 inEnd 的初始值應當為 0 和 len-1 .
* 當中序序列和前序序列不能構造一棵二叉樹時,此函數不會左任何檢測。
*/ struct node* buildTree(char in[], char pre[], int inStrt, int inEnd) { if (inStrt > inEnd) return NULL; // 利用索引 preIndex 從前序序列中取出一個元素,並利用此元素創建一個二叉樹結點 // 最后索引值 preIndex 加 1 struct node* tNode = newNode(pre[preIndex++]); // 如果此結點沒有孩子則返回 if (inStrt == inEnd) return tNode; //否則在中序序列中找到此元素的索引 int inIndex = search(in, inStrt, inEnd, tNode->data); // 利用中序索引構造左子樹與右子樹 tNode->left = buildTree(in, pre, inStrt, inIndex - 1); tNode->right = buildTree(in, pre, inIndex + 1, inEnd); return tNode; } /*
* 功能函數 * 此函數的功能是在數組 arr[start...end] 中查找值 value 的索引 * 此函數默認 value 在 arr[start...end] 中出現
*/ int search(char arr[], int strt, int end, char value) { int i; for (i = strt; i <= end; i++) { if (arr[i] == value) return i; } } /*
* 輔助函數
* 利用給定的數據域 data 分配一個新結點,該節點的 left 和 right 域均為 NULL
* 並返回指向該結點的指針
*/ struct node* newNode(char data) { struct node* node = (struct node*)malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return (node); } /*
* 為了驗證 buildTree()
*/ void printInorder(struct node* node) { if (node == NULL) return; printInorder(node->left); printf("%c ", node->data); printInorder(node->right); } int main() { char in[] = { 'D', 'B', 'E', 'A', 'F', 'C' }; char pre[] = { 'A', 'B', 'D', 'E', 'C', 'F' }; int len = sizeof(in) / sizeof(in[0]); struct node* root = buildTree(in, pre, 0, len - 1); printInorder(root); getchar(); }