用中序序列和前序序列构造二叉树

让我们考虑以下遍历结果:

中序序列:DBEAFC 
前序序列:ABDECF

在前序序列中, 最左边的元素是树的根。对于上面给定的序列,我们知道 ‘A’ 是树的根。

然后在中序序列中找到 ‘A’ 的位置,我们发现所有位于 ‘A’ 左边的元素存在于树的左子树,

位于 ‘A’ 右边的元素存在于树的右子树。

                 A
               /   \
             /       \
           D B E     F C

我们递归地按照上述步骤来构建整棵树。

         A
       /   \
     /       \
    B         C
   / \        /
 /     \    /
D       E  F

Algorithm

  定义函数 buildTree()

  1. 在前序序列中取出一个元素。增加前序序列索引变量,以便在下次递归调用过程中取下一个元素。
  2. 用取出元素作为数据域创建一个新节点 tNode。
  3. 在中序序列中查找取出元素的索引,赋值给 inIndex。
  4. 用 inIndex 之前的元素递归调用 buildTree()创建树,并将其作为  tNode 的左子树。
  5. 用 inIndex 之前的元素递归调用 buildTree()创建树,并将其作为  tNode 的右子树。
  6. 返回 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(); }
原文地址:https://www.cnblogs.com/xielei/p/10622356.html