😭
This commit is contained in:
+176
-176
@@ -1,176 +1,176 @@
|
||||
#ifndef BITREE_H
|
||||
#define BITREE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
template <typename T>
|
||||
class BiTree
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
BiTree* left;
|
||||
BiTree* right;
|
||||
|
||||
BiTree() : left(nullptr), right(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BiTree(char val): data(val), left(nullptr), right(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
static bool is_empty(BiTree* bt)
|
||||
{
|
||||
if (bt == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_leaf(BiTree* bt)
|
||||
{
|
||||
if (bt->left == nullptr && bt->right == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static T sum_leaf(BiTree* bt)
|
||||
{
|
||||
if (is_empty(bt))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (is_leaf(bt))
|
||||
{
|
||||
return bt->data;
|
||||
}
|
||||
return sum_leaf(bt->left) + sum_leaf(bt->right);
|
||||
}
|
||||
|
||||
static BiTree* createNode(const T& value)
|
||||
{
|
||||
BiTree* node = new BiTree();
|
||||
node->data = value;
|
||||
node->left = nullptr;
|
||||
node->right = nullptr;
|
||||
return node;
|
||||
}
|
||||
|
||||
static void insertNode(BiTree*& bt, T value)
|
||||
{
|
||||
if (bt == nullptr)
|
||||
{
|
||||
bt = createNode(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value < bt->data)
|
||||
{
|
||||
insertNode(bt->left, value);
|
||||
}
|
||||
if (value > bt->data)
|
||||
{
|
||||
insertNode(bt->right, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BiTree* buildFromPreorderString(const std::string& preorder, size_t& index)
|
||||
{
|
||||
if (index >= preorder.size() || preorder[index] == '#')
|
||||
{
|
||||
index++;
|
||||
return nullptr;
|
||||
}
|
||||
BiTree* node = createNode(preorder[index++]);
|
||||
node->left = buildFromPreorderString(preorder, index);
|
||||
node->right = buildFromPreorderString(preorder, index);
|
||||
return node;
|
||||
}
|
||||
|
||||
void inorderTraversal(std::ostringstream& oss) const
|
||||
{
|
||||
if (left) left->inorderTraversal(oss);
|
||||
oss << data;
|
||||
if (right) right->inorderTraversal(oss);
|
||||
}
|
||||
|
||||
static BiTree* buildFromPreorderInorderString(const std::string& preorder, const std::string& inorder, int preStart,
|
||||
int preEnd,
|
||||
int inStart, int inEnd, std::unordered_map<char, int>& inMap)
|
||||
{
|
||||
if (preStart > preEnd || inStart > inEnd)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char rootVal = preorder[preStart];
|
||||
BiTree* root = new BiTree(rootVal);
|
||||
|
||||
int inRoot = inMap[rootVal];
|
||||
int leftSubtreeSize = inRoot - inStart;
|
||||
|
||||
root->left = buildFromPreorderInorderString(preorder, inorder, preStart + 1, preStart + leftSubtreeSize,
|
||||
inStart, inRoot - 1, inMap);
|
||||
root->right = buildFromPreorderInorderString(preorder, inorder, preStart + leftSubtreeSize + 1, preEnd,
|
||||
inRoot + 1, inEnd, inMap);
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static int getHeight(BiTree* root)
|
||||
{
|
||||
if (root == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int leftHeight = getHeight(root->left);
|
||||
int rightHeight = getHeight(root->right);
|
||||
return 1 + std::max(leftHeight, rightHeight);
|
||||
}
|
||||
|
||||
void toStringHelper(std::ostringstream& oss, const std::string& prefix, bool isLeft, bool hasSibling) const
|
||||
{
|
||||
if (this != nullptr)
|
||||
{
|
||||
oss << prefix;
|
||||
oss << (isLeft ? (hasSibling ? "├─" : "└─") : (hasSibling ? "├─" : "└─")) << data << "\n";
|
||||
|
||||
std::string newPrefix = prefix + (isLeft ? (hasSibling ? "│ " : " ") : " ");
|
||||
bool hasLeftSibling = (left != nullptr && right != nullptr);
|
||||
|
||||
if (left) left->toStringHelper(oss, newPrefix, true, hasLeftSibling);
|
||||
if (right) right->toStringHelper(oss, newPrefix, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
this->toStringHelper(oss, "", false, false);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
left->destroy();
|
||||
delete left;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
right->destroy();
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITREE_H
|
||||
#ifndef BITREE_H
|
||||
#define BITREE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
template <typename T>
|
||||
class BiTree
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
BiTree* left;
|
||||
BiTree* right;
|
||||
|
||||
BiTree() : left(nullptr), right(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BiTree(char val): data(val), left(nullptr), right(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
static bool is_empty(BiTree* bt)
|
||||
{
|
||||
if (bt == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_leaf(BiTree* bt)
|
||||
{
|
||||
if (bt->left == nullptr && bt->right == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static T sum_leaf(BiTree* bt)
|
||||
{
|
||||
if (is_empty(bt))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (is_leaf(bt))
|
||||
{
|
||||
return bt->data;
|
||||
}
|
||||
return sum_leaf(bt->left) + sum_leaf(bt->right);
|
||||
}
|
||||
|
||||
static BiTree* createNode(const T& value)
|
||||
{
|
||||
BiTree* node = new BiTree();
|
||||
node->data = value;
|
||||
node->left = nullptr;
|
||||
node->right = nullptr;
|
||||
return node;
|
||||
}
|
||||
|
||||
static void insertNode(BiTree*& bt, T value)
|
||||
{
|
||||
if (bt == nullptr)
|
||||
{
|
||||
bt = createNode(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value < bt->data)
|
||||
{
|
||||
insertNode(bt->left, value);
|
||||
}
|
||||
if (value > bt->data)
|
||||
{
|
||||
insertNode(bt->right, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BiTree* buildFromPreorderString(const std::string& preorder, size_t& index)
|
||||
{
|
||||
if (index >= preorder.size() || preorder[index] == '#')
|
||||
{
|
||||
index++;
|
||||
return nullptr;
|
||||
}
|
||||
BiTree* node = createNode(preorder[index++]);
|
||||
node->left = buildFromPreorderString(preorder, index);
|
||||
node->right = buildFromPreorderString(preorder, index);
|
||||
return node;
|
||||
}
|
||||
|
||||
void inorderTraversal(std::ostringstream& oss) const
|
||||
{
|
||||
if (left) left->inorderTraversal(oss);
|
||||
oss << data;
|
||||
if (right) right->inorderTraversal(oss);
|
||||
}
|
||||
|
||||
static BiTree* buildFromPreorderInorderString(const std::string& preorder, const std::string& inorder, int preStart,
|
||||
int preEnd,
|
||||
int inStart, int inEnd, std::unordered_map<char, int>& inMap)
|
||||
{
|
||||
if (preStart > preEnd || inStart > inEnd)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char rootVal = preorder[preStart];
|
||||
BiTree* root = new BiTree(rootVal);
|
||||
|
||||
int inRoot = inMap[rootVal];
|
||||
int leftSubtreeSize = inRoot - inStart;
|
||||
|
||||
root->left = buildFromPreorderInorderString(preorder, inorder, preStart + 1, preStart + leftSubtreeSize,
|
||||
inStart, inRoot - 1, inMap);
|
||||
root->right = buildFromPreorderInorderString(preorder, inorder, preStart + leftSubtreeSize + 1, preEnd,
|
||||
inRoot + 1, inEnd, inMap);
|
||||
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static int getHeight(BiTree* root)
|
||||
{
|
||||
if (root == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int leftHeight = getHeight(root->left);
|
||||
int rightHeight = getHeight(root->right);
|
||||
return 1 + std::max(leftHeight, rightHeight);
|
||||
}
|
||||
|
||||
void toStringHelper(std::ostringstream& oss, const std::string& prefix, bool isLeft, bool hasSibling) const
|
||||
{
|
||||
if (this != nullptr)
|
||||
{
|
||||
oss << prefix;
|
||||
oss << (isLeft ? (hasSibling ? "├─" : "└─") : (hasSibling ? "├─" : "└─")) << data << "\n";
|
||||
|
||||
std::string newPrefix = prefix + (isLeft ? (hasSibling ? "│ " : " ") : " ");
|
||||
bool hasLeftSibling = (left != nullptr && right != nullptr);
|
||||
|
||||
if (left) left->toStringHelper(oss, newPrefix, true, hasLeftSibling);
|
||||
if (right) right->toStringHelper(oss, newPrefix, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
this->toStringHelper(oss, "", false, false);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
left->destroy();
|
||||
delete left;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
right->destroy();
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BITREE_H
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
project(homework4)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(test1 test1.cpp BiTree.h)
|
||||
add_executable(test2 test2.cpp BiTree.h)
|
||||
add_executable(test3 test3.cpp BiTree.h)
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
project(homework4)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(test1 test1.cpp BiTree.h)
|
||||
add_executable(test2 test2.cpp BiTree.h)
|
||||
add_executable(test3 test3.cpp BiTree.h)
|
||||
|
||||
+42
-42
@@ -1,42 +1,42 @@
|
||||
/*
|
||||
* 二叉树采用二叉链存储结构存放,结点值为int 类型,设计一个递归算法求二叉树 bt 中所有叶子结点值之和
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "BiTree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
BiTree<int>* createTreeFromArray(const int* values, int size)
|
||||
{
|
||||
BiTree<int>* root = nullptr;
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
BiTree<int>::insertNode(root, values[i]);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int testValues[] = {7, 3, 10, 1, 5, 9, 12};
|
||||
int size = sizeof(testValues) / sizeof(testValues[0]);
|
||||
|
||||
BiTree<int>* root = createTreeFromArray(testValues, size);
|
||||
|
||||
if (root)
|
||||
{
|
||||
cout << "树结构为:" << endl;
|
||||
cout << root->toString() << endl;
|
||||
|
||||
cout << "叶子节点数据总和: " << BiTree<int>::sum_leaf(root) << endl;
|
||||
|
||||
root->destroy();
|
||||
delete root;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "树为空。" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* 二叉树采用二叉链存储结构存放,结点值为int 类型,设计一个递归算法求二叉树 bt 中所有叶子结点值之和
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "BiTree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
BiTree<int>* createTreeFromArray(const int* values, int size)
|
||||
{
|
||||
BiTree<int>* root = nullptr;
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
BiTree<int>::insertNode(root, values[i]);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int testValues[] = {7, 3, 10, 1, 5, 9, 12};
|
||||
int size = sizeof(testValues) / sizeof(testValues[0]);
|
||||
|
||||
BiTree<int>* root = createTreeFromArray(testValues, size);
|
||||
|
||||
if (root)
|
||||
{
|
||||
cout << "树结构为:" << endl;
|
||||
cout << root->toString() << endl;
|
||||
|
||||
cout << "叶子节点数据总和: " << BiTree<int>::sum_leaf(root) << endl;
|
||||
|
||||
root->destroy();
|
||||
delete root;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "树为空。" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+49
-49
@@ -1,49 +1,49 @@
|
||||
/*
|
||||
* 以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’, 表示该二叉树是空树,否则该字符是相应结点的数据元素。读入相应先序序列,建立二叉链式存储结构的二叉树,然后中序遍历该二叉树并输出结点数据。
|
||||
* 输入格式:
|
||||
* 字符串形式的先序序列(即结点的数据类型为单个字符)
|
||||
* 输出格式:
|
||||
* 中序遍历结果
|
||||
* 输入样例:
|
||||
* 在这里给出一组输入。例如:
|
||||
* ABC##DE#G##F###
|
||||
* 输出样例:
|
||||
* CBEGDFA
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "BiTree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
string input;
|
||||
cout << "请输入二叉树的先序序列(如ABC##DE#G##F###):";
|
||||
cin >> input;
|
||||
|
||||
size_t index = 0;
|
||||
BiTree<char>* root = BiTree<char>::buildFromPreorderString(input, index); // 构建字符型二叉树
|
||||
|
||||
ostringstream oss;
|
||||
if (root)
|
||||
{
|
||||
// 中序遍历
|
||||
root->inorderTraversal(oss);
|
||||
cout << "中序遍历结果:" << oss.str() << endl;
|
||||
|
||||
// 打印树结构
|
||||
cout << "该树结构为:" << endl;
|
||||
cout << root->toString();
|
||||
|
||||
// 销毁树,释放内存
|
||||
root->destroy();
|
||||
delete root;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "输入的二叉树为空。" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* 以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’, 表示该二叉树是空树,否则该字符是相应结点的数据元素。读入相应先序序列,建立二叉链式存储结构的二叉树,然后中序遍历该二叉树并输出结点数据。
|
||||
* 输入格式:
|
||||
* 字符串形式的先序序列(即结点的数据类型为单个字符)
|
||||
* 输出格式:
|
||||
* 中序遍历结果
|
||||
* 输入样例:
|
||||
* 在这里给出一组输入。例如:
|
||||
* ABC##DE#G##F###
|
||||
* 输出样例:
|
||||
* CBEGDFA
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "BiTree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
string input;
|
||||
cout << "请输入二叉树的先序序列(如ABC##DE#G##F###):";
|
||||
cin >> input;
|
||||
|
||||
size_t index = 0;
|
||||
BiTree<char>* root = BiTree<char>::buildFromPreorderString(input, index); // 构建字符型二叉树
|
||||
|
||||
ostringstream oss;
|
||||
if (root)
|
||||
{
|
||||
// 中序遍历
|
||||
root->inorderTraversal(oss);
|
||||
cout << "中序遍历结果:" << oss.str() << endl;
|
||||
|
||||
// 打印树结构
|
||||
cout << "该树结构为:" << endl;
|
||||
cout << root->toString();
|
||||
|
||||
// 销毁树,释放内存
|
||||
root->destroy();
|
||||
delete root;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "输入的二叉树为空。" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+41
-41
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
* 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
|
||||
* 输入格式:
|
||||
* 输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。
|
||||
* 输出格式:
|
||||
* 输出为一个整数,即该二叉树的高度。
|
||||
* 输入样例:
|
||||
* 9
|
||||
* ABDFGHIEC
|
||||
* FDHGIBEAC
|
||||
* 输出样例:
|
||||
* 5
|
||||
*/
|
||||
#include"BiTree.h"
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int n;
|
||||
cout << "请输入节点个数:";
|
||||
cin >> n;
|
||||
|
||||
string preorder, inorder;
|
||||
cout << "请输入前置索引:" << endl;
|
||||
cin >> preorder;
|
||||
cout << "请输入后置索引:" << endl;
|
||||
cin >> inorder;
|
||||
|
||||
std::unordered_map<char, int> inMap;
|
||||
for (int i = 0; i < inorder.size(); ++i)
|
||||
{
|
||||
inMap[inorder[i]] = i;
|
||||
}
|
||||
|
||||
BiTree<char>* root = BiTree<char>::buildFromPreorderInorderString(preorder, inorder, 0, n - 1, 0, n - 1, inMap);
|
||||
|
||||
cout << "树高为:" << BiTree<char>::getHeight(root) << endl;
|
||||
cout << "该数结构为:" << endl << root->toString() << endl;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
|
||||
* 输入格式:
|
||||
* 输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。
|
||||
* 输出格式:
|
||||
* 输出为一个整数,即该二叉树的高度。
|
||||
* 输入样例:
|
||||
* 9
|
||||
* ABDFGHIEC
|
||||
* FDHGIBEAC
|
||||
* 输出样例:
|
||||
* 5
|
||||
*/
|
||||
#include"BiTree.h"
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int n;
|
||||
cout << "请输入节点个数:";
|
||||
cin >> n;
|
||||
|
||||
string preorder, inorder;
|
||||
cout << "请输入前置索引:" << endl;
|
||||
cin >> preorder;
|
||||
cout << "请输入后置索引:" << endl;
|
||||
cin >> inorder;
|
||||
|
||||
std::unordered_map<char, int> inMap;
|
||||
for (int i = 0; i < inorder.size(); ++i)
|
||||
{
|
||||
inMap[inorder[i]] = i;
|
||||
}
|
||||
|
||||
BiTree<char>* root = BiTree<char>::buildFromPreorderInorderString(preorder, inorder, 0, n - 1, 0, n - 1, inMap);
|
||||
|
||||
cout << "树高为:" << BiTree<char>::getHeight(root) << endl;
|
||||
cout << "该数结构为:" << endl << root->toString() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user