C++ - 二叉树(数组形式、节点形式 相互转换)

1. 树节点及树

1.1 节点

节点:也称之为叶子。二叉树节点最大不超过两个。节点存放子节点(子节点有左子节点和右子节点)。value为该节点存储的数据。

class Node
{
public:
	Node(int v)
	{
		value = v;
		left = nullptr;
		right = nullptr;
	}
public:
	int value;
	Node* left;
	Node* right;
};

1.2 树

树:存储根节点。

#define null INT_MIN
class BinaryTree
{
public:
	BinaryTree()
	{
		root = nullptr;
	}
public:
	Node* root;
};

2. 树的创建、转换及遍历等

2.1 创建二叉树

提供了二叉树的创建方法,利用vector数组进行创建二叉树。即是从“数组形式”向“节点形式转换”。

当我们使用数组来表示二叉树时,可以使用以下规则:
对于任意节点的索引 i,它的左子节点的索引为 2i+1,右子节点的索引为 2i+2。
如果某个节点的索引为 i,那么它的父节点的索引为 (i-1)/2。

转换算法思路如下:数组位置0的元素为根节点, 函数createTree有两种形式。

  1. 函数 void createTree(std::vector& data) 仅仅是为了调用另一个createTree函数。
  2. 函数 void createTree(int nIndex, Node* parentNode, std::vector& data) 提供了三个参数,nIndex代表为data[nIndex]元素创建节点, parentNode节点为记录上一个节点,这样就可以链接左节点或者右节点。执行流程:

从根节点开始,为当前data[nIndex]创建一个节点并链接到父节点上。根据(nIndex - 1) % 2确定左右节点。 递归调用createTree创建左节点及创建右节点。

void createTree(std::vector<int>& data)
{
	if (root != nullptr)
		return;

	createTree(0, nullptr, data);
}

void createTree(int nIndex, Node* parentNode, std::vector<int>& data)
{
	if (data[nIndex] == null)
		return;

	if (parentNode == nullptr)
	{
		root = new Node(data[nIndex]);
		createTree(2 * nIndex + 1, root, data);
		createTree(2 * nIndex + 2, root, data);
		return;
	}

	Node* tmpNode = new Node(data[nIndex]);
	if ((nIndex - 1) % 2 == 0)
	{
		parentNode->left = tmpNode;
	}
	else
	{
		parentNode->right = tmpNode;
	}

	createTree(2 * nIndex + 1, tmpNode, data);
	createTree(2 * nIndex + 2, tmpNode, data);
}

2.2 二叉树的遍历

二叉树的遍历方式有三种:前序遍历,中序遍历,后序遍历。命名方式主要根据根节点访问顺序相关。
前序遍历:先访问根节点,然后左节点,后面再访问右节点。
中序遍历:先访问左节点,然后根节点,后面访问右节点。
后序遍历:先访问左节点,然后右节点,最后访问根节点。

2.2.1 前序遍历
void traversal(Node* node)
{
	if (node == nullptr)
		return;

	std::cout << node->value << ",";
	traversal(node->left);
	traversal(node->right);

	if (node == root)
		std::cout << "\n";
}
2.2.2 中序遍历
void midTraversal(Node* node)
{
	if (node == nullptr)
		return;

	midTraversal(node->left);
	midTraversal(node->right);
	std::cout << node->value << ",";

	if (node == root)
		std::cout << "\n";
}
2.2.3 后序遍历
void lastTraversal(Node* node)
{

	if (node == nullptr)
		return;

	lastTraversal(node->left);
	lastTraversal(node->right);
	std::cout << node->value << ",";

	if (node == root)
		std::cout << "\n";
}

2.3 二叉树的深度

void depth(Node* node, int nDepth, int &nMaxDepth)
{
	if (node == nullptr)
	{
		if (nDepth > nMaxDepth)
			nMaxDepth = nDepth;

		return;
	}

	depth(node->left, nDepth + 1, nMaxDepth);
	depth(node->right, nDepth + 1, nMaxDepth);
}

3 完整示例代码

#include <iostream>
#include <vector>
#include <cmath>

class Node
{
public:
	Node(int v)
	{
		value = v;
		left = nullptr;
		right = nullptr;
	}
public:
	int value;
	Node* left;
	Node* right;
};

#define null INT_MIN
class BinaryTree
{
public:
	BinaryTree()
	{
		root = nullptr;
	}

	~BinaryTree()
	{
		freeNode(root);
	}

	void createTree(std::vector<int>& data)
	{
		if (root != nullptr)
			return;

		createTree(0, nullptr, data);
	}

	void createTree(int nIndex, Node* parentNode, std::vector<int>& data)
	{
		if (data[nIndex] == null)
			return;

		if (parentNode == nullptr)
		{
			root = new Node(data[nIndex]);
			createTree(2 * nIndex + 1, root, data);
			createTree(2 * nIndex + 2, root, data);
			return;
		}

		Node* tmpNode = new Node(data[nIndex]);
		if ((nIndex - 1) % 2 == 0)
		{
			parentNode->left = tmpNode;
		}
		else
		{
			parentNode->right = tmpNode;
		}

		createTree(2 * nIndex + 1, tmpNode, data);
		createTree(2 * nIndex + 2, tmpNode, data);
	}

	std::vector<int> translateTree()
	{
		int dataSize = std::pow(2, depth() + 1);
		std::vector<int> data;
		data.assign(dataSize, null);

		translateTree(-1, root, nullptr, data);
		return data;
	}

	void translateTree(int nParentIndex, Node* node, Node* parentNode, std::vector<int>& data)
	{
		if ((nParentIndex * 2  + 2) >= data.size())
			return;

		if (node == nullptr)
			return;

		if (nParentIndex == -1)
		{
			data[0] = node->value;
			translateTree(0, node->left, node, data);
			translateTree(0, node->right, node, data);
			return;
		}

		if (parentNode->left == node)
		{
			nParentIndex = nParentIndex * 2 + 1;
			data[nParentIndex] = node->value;
			translateTree(nParentIndex, node->left, node, data);
			translateTree(nParentIndex, node->right, node, data);
		}

		if (parentNode->right == node)
		{
			nParentIndex = nParentIndex * 2 + 2;
			data[nParentIndex] = node->value;
			translateTree(nParentIndex, node->left, node, data);
			translateTree(nParentIndex, node->right, node, data);
		}
	}

	void depth(Node* node, int nDepth, int &nMaxDepth)
	{
		if (node == nullptr)
		{
			if (nDepth > nMaxDepth)
				nMaxDepth = nDepth;

			return;
		}

		depth(node->left, nDepth + 1, nMaxDepth);
		depth(node->right, nDepth + 1, nMaxDepth);
	}

	int depth()
	{
		int nMaxDepth = 0;
		int nDepth = 0;
		depth(root, nDepth, nMaxDepth);
		return nMaxDepth;
	}

	void traversal(Node* node)
	{
		if (node == nullptr)
			return;

		std::cout << node->value << ",";
		traversal(node->left);
		traversal(node->right);

		if (node == root)
			std::cout << "\n";
	}

	void preTraversal(Node* node)
	{

		if (node == nullptr)
			return;

		std::cout << node->value << ",";
		preTraversal(node->left);
		preTraversal(node->right);

		if (node == root)
			std::cout << "\n";
	}

	void midTraversal(Node* node)
	{

		if (node == nullptr)
			return;

		midTraversal(node->left);
		midTraversal(node->right);
		std::cout << node->value << ",";

		if (node == root)
			std::cout << "\n";
	}

	void lastTraversal(Node* node)
	{

		if (node == nullptr)
			return;

		lastTraversal(node->left);
		lastTraversal(node->right);
		std::cout << node->value << ",";

		if (node == root)
			std::cout << "\n";
	}

	void freeNode(Node* node)
	{
		if (node == nullptr)
			return;

		freeNode(node->left);
		freeNode(node->right);
		delete node;
	}
public:
	Node* root;
};

int main(int argc, char** argv)
{
	std::vector<int> data {1, 2, 3, 4, null, 6, 7, null, null, null, null, null, null, null, null};
	BinaryTree bT;
	bT.createTree(data);
	bT.preTraversal(bT.root);
	bT.lastTraversal(bT.root);

	std::cout << "max depth:" <<  bT.depth() << std::endl;
	std::vector<int> tmpData = bT.translateTree();

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

莫忘输赢

莫忘输赢 - 收钱袋

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

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

打赏作者

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

抵扣说明:

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

余额充值