[数据结构] C/C++重建二叉树

本文详细介绍了使用前序、中序及后序遍历序列构建二叉树的算法实现,包括C语言和C++的代码示例。通过递归方法,文章展示了如何从不同的遍历序列中重构出原始的二叉树结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值