C语言
#pragma once
typedef struct Node {
char value;
struct Node *left;
struct Node *right;
} Node;
前序创建二叉树
Node * CreateTree(char preorder[], int size, int *pUsed) {
if (size == 0) {
*pUsed = 0;
return NULL;
}
else if (preorder[0] == '#') {
*pUsed = 1;
return NULL;
}
else {
// 根
Node *root = (Node *)malloc(sizeof(Node));
root->value = preorder[0];
// 左子树
int leftUsed; // 用来保存创建左子树用掉的个数
int rightUsed; // 用来保存创建右子树用掉的个数
root->left = CreateTree(preorder + 1, size - 1, &leftUsed);
root->right = CreateTree(
preorder + 1 + leftUsed,
size - 1 - leftUsed, &rightUsed);
*pUsed = 1 + leftUsed + rightUsed; // 根用掉 + 左子树用掉 + 右子树用掉
return root;
}
}
测试代码
void Test1() {
char *preorder = "ABD##E#H##CF##G";
int size = strlen(preorder);
int used;
Node *root = CreateTree(preorder, size, &used);
assert(used == size);
}
前序、中序创建二叉树
int Find(char array[], int size, char v) {
for (int i = 0; i < size; i++) {
if (array[i] == v) {
return i;
}
}
return -1;
}
Node * buildTree(char preorder[], char inorder[], int size) {
if (size == 0) {
return NULL;
}
char rootValue = preorder[0];
int leftSize = Find(inorder, size, rootValue);
// 根
Node *root = (Node *)malloc(sizeof(Node));
root->value = rootValue;
// 左子树
root->left = buildTree(preorder + 1, inorder, leftSize);
// 右子树
root->right = buildTree(preorder + 1 + leftSize,
inorder + leftSize + 1, size - 1 - leftSize);
return root;
}
测试代码
void Test2() {
char *preorder = "ABDEHCFG";
char *inorder = "DBEHAFCG";
int size = strlen(preorder);
Node *root = buildTree(preorder, inorder, size);
}
中序、后序创建二叉树
int Find2(char array[], int size, char value) {
for (int i = 0; i < size; i++) {
if (array[i] == value) {
return i;
}
}
return -1;
}
// inorder D B E H A F C G
// postorder D H E B F G C A
Node * buildTree2(char inorder[], char postorder[], int size) {
if (size == 0) {
return NULL;
}
char rootValue = postorder[size - 1]; //后序最后一个结点值
int leftSize = Find2(inorder, size, rootValue); //在中序找到对应的结点下标
Node *root = (Node *)malloc(sizeof(Node));
root->value = rootValue;
root->left = buildTree2(inorder, postorder, leftSize);
root->right = buildTree2(inorder + leftSize + 1,
postorder + leftSize, size - 1 - leftSize);
return root;
}
测试代码
void Test3() {
char *postorder = "DHEBFGCA";
char *inorder = "DBEHAFCG";
int size = strlen(postorder);
Node *root = buildTree2(inorder, postorder,size);
}
C++
前序、中序重建二叉树
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (pre.empty() || vin.empty()) return nullptr;
vector<int> pre_left, pre_right;
vector<int> in_left, in_right;
//创建根节点,根节点肯定是前序遍历的第一个数
TreeNode *root = new TreeNode(pre[0]);
//找到中序遍历根节点所在位置,存放于变量bound中
int bound = 0;
for (; bound < vin.size(); bound++) {
if (vin[bound] == root->val) break;
}
//对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边
//利用上述这点,对二叉树节点进行归并
for (int i = 0; i < bound; i++) {
in_left.push_back(vin[i]);
pre_left.push_back(pre[i + 1]); //前序第一个为根节点
}
for (int i = bound + 1; i < vin.size(); i++) {
in_right.push_back(vin[i]);
pre_right.push_back(pre[i]);
}
//和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树
//递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
root->left = reConstructBinaryTree(pre_left, in_left);
root->right = reConstructBinaryTree(pre_right, in_right);
return root;
}