简介
简单的二叉数类,支持结构化字符串和中序遍历+任意一种其他遍历方式来建立一颗STL风格的二叉树。
所谓结构化字符串,即以ROOT[(LEFT[,RIGHT])]来表示一个节点和其左右子树结构,无右子树可省略逗号,无子树可省略括号,如0(1(,2),3(4,5(6(7,8),9)))中根节点为0,左子树为1(,2),右子树为3(4,5(6(7,8),9))。结构如下:
测试代码
int main()
{
BinTree<string> bts("0(1(3,4),2(5,6))", vector<string>{"a", "b", "c", "d", "e", "f", "g"});
cout << "bts:" << endl; bts.show(); // 左转90°打印树
BinTree<uint> bt1("1(2(4),3(5(,7),6))");
cout << "bt1:" << endl; bt1.show();
BinTree<uint> bt2(bt1); // 拷贝构造
BinTree<uint> bt3, bt4, bt5;
bt3.fromPreorder(bt1.inorder(), bt1.preorder()); // 中序 + 先序 重建二叉树
bt4.fromPostorder(bt2.inorder(), bt2.postorder()); // 中序 + 后序 重建二叉树
bt5.fromLevelorder(bt3.inorder(), bt3.levelorder()); // 中序 + 层序 重建二叉树
cout << "bt1 == bt2: " << (bt1 == bt2) << endl;
cout << "bt2 == bt3: " << (bt2 == bt3) << endl;
cout << "bt3 == bt4: " << (bt3 == bt4) << endl;
cout << "bt4 == bt5: " << (bt4 == bt5) << endl;
cout << "levelorder: ";
for (cosnt auto& x : bt2.levelorder()) // 层序遍历
cout << x << ' ';
cout << endl;
cout << "preorder: ";
for (cosnt auto& x : bt3.preorder()) // 先序遍历
cout << x << ' ';
cout << endl;
cout << "inorder: ";
for (cosnt auto& x : bt4.inorder()) // 中序遍历
cout << x << ' ';
cout << endl;
cout << "postorder: ";
for (cosnt auto& x : bt5.postorder()) // 后序遍历
cout << x << ' ';
cout << endl;
cout << "depth: " << bt1.depth() << endl; // 树的高度
cout << "size: " << bt1.size() << endl; // 树的结点数
return 0;
}
测试效果
代码
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<tuple>
#include<unordered_map>
#include<iostream>
using namespace std;
typedef unsigned int uint;
template<typename T>
struct TreeNode {
uint id;
T val;
TreeNode<T>* left;
TreeNode<T>* right;
TreeNode(uint id, T val) :id(id), val(val), left(nullptr), right(nullptr) {}
~TreeNode() {
if (left != nullptr) delete left;
if (right != nullptr) delete right;
}
};
template<typename T>
class BinTree {
private:
TreeNode<T>* root;
static bool isVaild(const string& treestr) { // 判断格式字符串是否合法
uint count = 0;
for (auto c : treestr) {
if (c == '(') ++count;
else if (c == ')') --count;
if (count < 0) return false;
}
if (count == 0) return true;
else return false;
}
static uint treestrSplit(const string& treestr, string& left, string& right) { // 分割格式字符串
auto index = treestr.find('(');
if (index == string::npos) {
left.clear();
right.clear();
return stoi(treestr);
}
uint count = 0;
auto i = index + 1;
for (;i < treestr.size();++i) {
if (treestr[i] == '(') ++count;
else if (treestr[i] == ')') --count;
else if (treestr[i] == ',' && count == 0) {
left = treestr.substr(index + 1, i - index - 1);
right = treestr.substr(i + 1, treestr.size() - i - 2);
break;
}
}
if (i == treestr.size()) {
left = treestr.substr(index + 1, treestr.size() - index - 2);
right.clear();
}
return stoi(treestr.substr(0, index));
}
static TreeNode<T>* buildTree(const string& treestr, const vector<T>& data) { // 根据格式字符串递归构建二叉树
if (treestr.empty()) return nullptr;
string left, right;
uint id = treestrSplit(treestr, left, right);
T val;
if (data.empty() && typeid(T) == typeid(uint)) val = id;
else val = data[id];
TreeNode<T>* node = new TreeNode<T>(id, val);
node->left = buildTree(left, data);
node->right = buildTree(right, data);
return node;
}
static string buildStr(TreeNode<T>* node) { // 根据二叉树递归构建格式字符串
if (node == nullptr) return "";
string str = to_string(node->id), left = buildStr(node->left), right = buildStr(node->right);
if (!left.empty()) {
str += '(';
str += left;
if (!right.empty()) {
str += ',';
str += right;
}
str += ')';
}
else if (!right.empty()) {
str += "(,";
str += right + ')';
}
return str;
}
static TreeNode<T>* copyTree(const TreeNode<T>* other) { // 根据二叉树递归复制二叉树
if (other == nullptr) return nullptr;
TreeNode<T>* node = new TreeNode<T>(other->id, other->val);
node->left = copyTree(other->left);
node->right = copyTree(other->right);
return node;
}
static TreeNode<T>* buildByPre(int low, int high, unordered_map<uint, uint> inorder, vector<uint>& preorder, vector<T>& data) {
// 根据中序先序遍历递归构造二叉树
if (low > high) return nullptr;
uint id = preorder.back();
preorder.pop_back();
T val;
if (data.empty() && typeid(T) == typeid(uint)) val = id;
else val = data[id];
TreeNode<T>* node = new TreeNode<T>(id, val);
uint index = inorder[node->id];
node->left = buildByPre(low, index - 1, inorder, preorder, data);
node->right = buildByPre(index + 1, high, inorder, preorder, data);
return node;
}
static TreeNode<T>* buildByPost(int low, int high, unordered_map<uint, uint> inorder, vector<uint>& postorder, vector<T>& data) {
// 根据中序后序遍历递归构造二叉树
if (low > high) return nullptr;
uint id = postorder.back();
postorder.pop_back();
T val;
if (data.empty() && typeid(T) == typeid(uint)) val = id;
else val = data[id];
TreeNode<T>* node = new TreeNode<T>(id, val);
uint index = inorder[node->id];
node->right = buildByPost(index + 1, high, inorder, postorder, data);
node->left = buildByPost(low, index - 1, inorder, postorder, data);
return node;
}
static void levelToPre(int low, int high, const vector<uint>& inorder, const vector<uint>& levelorder, vector<uint>& preorder) {
// 根据中序层序遍历求出前序遍历
for (auto n : levelorder) {
for (auto i = low; i <= high; ++i) {
if (inorder[i] == n) {
preorder.push_back(n);
if (i > low) levelToPre(low, i - 1, inorder, levelorder, preorder);
if (i < high) levelToPre(i + 1, high, inorder, levelorder, preorder);
return;
}
}
}
}
static uint getDepth(const TreeNode<T>* node) { // 递归计算树高
if (node == nullptr) return 0;
return max(getDepth(node->left), getDepth(node->right)) + 1;
}
static uint getSize(const TreeNode<T>* node) { // 递归计算结点数
if (node == nullptr) return 0;
return getSize(node->left) + getSize(node->right) + 1;
}
static bool eq(const TreeNode<T>* node, const TreeNode<T>* other) { // 递归比较二叉树
if (node == other) return true;
if (node == nullptr || other == nullptr) return false;
if (node->val != other->val) return false;
return eq(node->left, other->left) && eq(node->right, other->right);
}
public:
BinTree() { root = nullptr; }
BinTree(const string& treestr, const vector<T>& data = {}) { // 根据格式字符串和值列表(可选)构建二叉树
if (isVaild(treestr)) root = buildTree(treestr, data);
else throw treestr + " is not a vaild treestr.";
}
BinTree(BinTree<T>& other) { // 拷贝构造函数
root = copyTree(other.getRoot());
}
~BinTree() {
if (root != nullptr) delete root;
}
bool fromPreorder(vector<uint> inorder, vector<uint> preorder, vector<T> data = {}) {
// 根据中序遍历 + 先序遍历构建二叉树
if (root != nullptr) return false;
unordered_map<uint, uint> inorder_map;
reverse(preorder.begin(), preorder.end());
for (uint i = 0; i < inorder.size(); ++i)
inorder_map[inorder[i]] = i;
root = buildByPre(0, preorder.size() - 1, inorder_map, preorder, data);
return true;
}
bool fromPostorder(vector<uint> inorder, vector<uint> postorder, vector<T> data = {}) {
// 根据中序遍历 + 后序遍历构建二叉树
if (root != nullptr) return false;
unordered_map<uint, uint> inorder_map;
for (uint i = 0; i < inorder.size(); ++i)
inorder_map[inorder[i]] = i;
root = buildByPost(0, postorder.size() - 1, inorder_map, postorder, data);
return true;
}
bool fromLevelorder(vector<uint> inorder, vector<uint> levelorder, vector<T> data = {}) {
// 根据中序遍历 + 层序遍历构建二叉树
if (root != nullptr) return false;
vector<uint> preorder;
levelToPre(0, inorder.size() - 1, inorder, levelorder, preorder);
return fromPreorder(inorder, preorder, data);
}
string getTreestr() { // 返回二叉树的格式字符串
return buildStr(root);
}
const TreeNode<T>* getRoot() { // 返回二叉树根节点
return root;
}
uint depth() { // 返回二叉数高度
return getDepth(root);
}
uint size() { // 返回二叉数结点数
return getSize(root);
}
void show() { // 左转90°打印二叉树结点
stack<uint> levels;
stack<TreeNode<T>*> nodes;
TreeNode<T>* node = root;
uint level = 0;
while (node != nullptr || !nodes.empty()) {
if (node != nullptr) {
levels.push(level);
nodes.push(node);
++level;
node = node->right;
}
else {
level = levels.top();
levels.pop();
node = nodes.top();
nodes.pop();
cout << string(3 * level, ' ');
cout << node->val << endl;
node = node->left;
++level;
}
}
}
vector<T> levelorder() { // 返回层序遍历二叉树的vector<val>
if (root == nullptr) return {};
vector<T> res;
queue<TreeNode<T>*> que;
TreeNode<T>* node;
que.push(root);
while (!que.empty()) {
node = que.front();
que.pop();
if (node->left != nullptr) que.push(node->left);
if (node->right != nullptr) que.push(node->right);
res.push_back(node->val);
}
return res;
}
vector<T> preorder() { // 返回先序遍历二叉树的vector<val>
if (root == nullptr) return {};
vector<T> res;
stack<TreeNode<T>*> stk;
TreeNode<T>* node;
stk.push(root);
while (!stk.empty()) {
node = stk.top();
stk.pop();
if (node->right != nullptr) stk.push(node->right);
if (node->left != nullptr) stk.push(node->left);
res.push_back(node->val);
}
return res;
}
vector<T> inorder() { // 返回中序遍历二叉树的vector<val>
if (root == nullptr) return {};
vector<T> res;
stack<TreeNode<T>*> stk;
TreeNode<T>* node = root;
while (node != nullptr || !stk.empty()) {
while (node != nullptr) {
stk.push(node);
node = node->left;
}
node = stk.top();
stk.pop();
res.push_back(node->val);
node = node->right;
}
return res;
}
vector<T> postorder() { // 返回后序遍历二叉树的vector<val>
if (root == nullptr) return {};
vector<T> res;
stack<TreeNode<T>*> stk;
TreeNode<T>* node;
stk.push(root);
while (!stk.empty()) {
node = stk.top();
stk.pop();
if (node->left != nullptr) stk.push(node->left);
if (node->right != nullptr) stk.push(node->right);
res.push_back(node->val);
}
reverse(res.begin(), res.end());
return res;
}
bool operator== (BinTree<T>& other) { // 判断二叉树相等(仅判断对应结点val是否相等,无视结点id)
return eq(root, other.getRoot());
}
bool operator!= (BinTree<T>& other) {
return !eq(root, other.getRoot());
}
};