节点:也称之为叶子。二叉树节点最大不超过两个。节点存放子节点(子节点有左子节点和右子节点)。value为该节点存储的数据。
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;
}
public:
Node* root;
};
提供了二叉树的创建方法,利用vector数组进行创建二叉树。即是从“数组形式”向“节点形式转换”。
当我们使用数组来表示二叉树时,可以使用以下规则:
对于任意节点的索引 i,它的左子节点的索引为 2i+1,右子节点的索引为 2i+2。
如果某个节点的索引为 i,那么它的父节点的索引为 (i-1)/2。
转换算法思路如下:数组位置0的元素为根节点, 函数createTree有两种形式。
- 函数 void createTree(std::vector& data) 仅仅是为了调用另一个createTree函数。
- 函数 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);
}
二叉树的遍历方式有三种:前序遍历,中序遍历,后序遍历。命名方式主要根据根节点访问顺序相关。
前序遍历:先访问根节点,然后左节点,后面再访问右节点。
中序遍历:先访问左节点,然后根节点,后面访问右节点。
后序遍历:先访问左节点,然后右节点,最后访问根节点。
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 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 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);
}
#include
#include
#include
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;
}