数据结构——第七章作业

This commit is contained in:
423A35C7 2023-12-16 16:19:59 +08:00
parent 2fc297ab49
commit 7d46b1ef7c
11 changed files with 13911 additions and 0 deletions

View File

@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.26)
project(chapter7)
set(CMAKE_CXX_STANDARD 23)
add_executable(binsort1 第七章作业1.cpp)
add_executable(binsort2 第七章作业2.cpp)
#set(EXECUTABLE_OUTPUT_PATH R:/) # WSL
#set(CMAKE_CXX_FLAGS_RELEASE -fexec-charset=GBK) # WSLLinuxUTF-8

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
41 40 19 8 5 5 17 32 39 32 98 95 68 56 60 59 67 94 77 98

View File

@ -0,0 +1,128 @@
//
// Created by 423A35C7 on 2023-12-14.
//
// 20:30
// 22:20
#include <algorithm>
#include <fstream>
#include <functional>
#include <iostream>
#include <memory>
#include <vector>
template<typename T>
class BiSortNode {
std::unique_ptr<BiSortNode> left_child;
std::unique_ptr<BiSortNode> right_child;
T data;
std::function<bool(T&, T&)> compare_function_;
public:
// 好像这里没法使用initializer_listinitializer_list是对于多个相同值的初始化而不是一个东西的初始化参数列表
template<typename... Args>
explicit BiSortNode(Args... args, std::function<bool(T&, T&)> _compare) : data(args...) {
this->compare_function_(_compare);
}
template<typename... Args>
explicit BiSortNode(Args... args) : data(args...) {
this->compare_function_ = [](T&a, T&b) { return a < b; };
}
void insert(T new_data) {
if (new_data < this->data) {
if (this->left_child == nullptr) {
this->left_child = std::make_unique<BiSortNode>(new_data);
}
else {
this->left_child->insert(new_data);
}
}
else {
if (this->right_child == nullptr) {
this->right_child = std::make_unique<BiSortNode>(new_data);
}
else {
this->right_child->insert(new_data);
}
}
}
void preorder_traversal(std::vector<T>&output) {
output.push_back(this->data);
if (this->left_child != nullptr) this->left_child->preorder_traversal(output);
if (this->right_child != nullptr) this->right_child->preorder_traversal(output);
}
void mirror_preorder_traversal(std::vector<T>&output) {
output.push_back(this->data);
if (this->right_child != nullptr) this->right_child->mirror_preorder_traversal(output);
if (this->left_child != nullptr) this->left_child->mirror_preorder_traversal(output);
}
void postorder_traversal(std::vector<T>&output) {
if (this->left_child != nullptr) this->left_child->postorder_traversal(output);
if (this->right_child != nullptr) this->right_child->postorder_traversal(output);
output.push_back(this->data);
}
void mirror_postorder_traversal(std::vector<T>&output) {
if (this->right_child != nullptr) this->right_child->mirror_postorder_traversal(output);
if (this->left_child != nullptr) this->left_child->mirror_postorder_traversal(output);
output.push_back(this->data);
}
};
int main() {
std::vector<int> origin_vector;
int temp;
while (std::cin >> temp) {
origin_vector.push_back(temp);
}
auto generator = origin_vector.cbegin();
BiSortNode<int> bi_sort_node{*generator++};
while (generator != origin_vector.cend()) {
bi_sort_node.insert(*generator++);
}
std::vector<int> preorder_traversal_result;
bi_sort_node.preorder_traversal(preorder_traversal_result);
std::vector<int> mirror_result;
bi_sort_node.mirror_preorder_traversal(mirror_result);
std::ofstream outfile;
outfile.open("temp_out.txt", std::ios::out);
if (origin_vector == preorder_traversal_result || origin_vector == mirror_result) {
std::cout << "Yes" << std::endl;
std::vector<int> post_result;
bi_sort_node.postorder_traversal(post_result);
for (const auto&i: post_result) {
std::cout << i << " ";
}
std::cout << std::endl;
std::vector<int> mirror_post_result;
bi_sort_node.mirror_postorder_traversal(mirror_post_result);
for (const auto&i: mirror_post_result) {
outfile << i << " ";
}
outfile << std::endl;
}
else {
std::cout << "No" << std::endl;
}
outfile.close();
return 0;
}
// 输入:
// 41 40 19 8 5 5 17 32 39 32 98 95 68 56 60 59 67 94 77 98
// 输出:
// Yes
// 5 5 17 8 32 39 32 19 40 59 67 60 56 77 94 68 95 98 98 41
// temp_out.txt 文件输出:
// 98 77 94 67 59 60 56 68 95 98 32 39 32 17 5 5 8 19 40 41

View File

@ -0,0 +1,167 @@
//
// Created by 423A35C7 on 2023-12-15.
//
// 09:19
// 20:06
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <vector>
template<typename T>
class BiSortNode {
public:
using NodePtr = std::unique_ptr<BiSortNode>;
// 好像这里没法使用initializer_listinitializer_list是对于多个相同值的初始化而不是一个东西的初始化参数列表
template<typename... Args>
explicit BiSortNode(Args... args, std::function<bool(T, T)> _compare) : data(args...) {
this->compare_function_(_compare);
}
template<typename... Args>
explicit BiSortNode(Args... args) : data(args...) {
this->compare_function_ = [](T&a, T&b) { return a < b; };
}
void update_depth_and_balance_factor() {
const int left_depth = this->left_child ? this->left_child->depth + 1 : 0;
const int right_depth = this->right_child ? this->right_child->depth + 1 : 0;
this->balance_factor = left_depth - right_depth;
this->depth = std::max(left_depth, right_depth);
}
// 这里的左旋指的是LL型需要进行的旋转名称不一定对
// 这部分用注释不好解释,建议最好搜一下网上的图解,理解了之后再看这部分代码
static void left_rotate(NodePtr&unbalanced) {
NodePtr pivot = std::move(unbalanced->left_child);
unbalanced->left_child = std::move(pivot->right_child);
pivot->right_child = std::move(unbalanced);
unbalanced = std::move(pivot);
unbalanced->update_depth_and_balance_factor();
unbalanced->right_child->update_depth_and_balance_factor();
}
// 这里的右旋指的是RR型需要进行的旋转名称不一定对
// 这部分用注释不好解释,建议最好搜一下网上的图解,理解了之后再看这部分代码
static void right_rotate(NodePtr&unbalanced) {
NodePtr pivot = std::move(unbalanced->right_child);
unbalanced->right_child = std::move(pivot->left_child);
pivot->left_child = std::move(unbalanced);
unbalanced = std::move(pivot);
unbalanced->update_depth_and_balance_factor();
unbalanced->left_child->update_depth_and_balance_factor();
}
static void insert(NodePtr&current_node, T new_data) {
// int balance_diff = 0;
if (new_data < current_node->data) {
// 如果新的节点比当前节点小就找它的左子树
if (current_node->left_child == nullptr) {
current_node->left_child = std::make_unique<BiSortNode>(new_data);
}
else {
current_node->insert(current_node->left_child, new_data);
}
}
else {
// 否则找右子树
if (current_node->right_child == nullptr) {
current_node->right_child = std::make_unique<BiSortNode>(new_data);
}
else {
current_node->insert(current_node->right_child, new_data);
}
}
current_node->update_depth_and_balance_factor();
if (current_node->balance_factor > 1) {
// 左子树比右子树高
assert(current_node->left_child->balance_factor != 0); // 此时左子树的平衡因子不应为0
if (current_node->left_child->balance_factor < 0) // 符合LR型
current_node->right_rotate(current_node->left_child); // 先进行右旋逆时针转化为LL
current_node->left_rotate(current_node); // 左旋(顺时针)
}
else if (current_node->balance_factor < -1) {
// 右子树比左子树高
assert(current_node->right_child->balance_factor != 0); // 此时右子树的平衡因子不应为0
if (current_node->right_child->balance_factor > 0) // 符合RL型
current_node->left_rotate(current_node->right_child); // 先进行左旋顺时针转化为RR型
current_node->right_rotate(current_node); // 右旋(逆时针)
}
// current_node->balance_factor += balance_diff;
current_node->update_depth_and_balance_factor();
// return balance_diff;
}
void inorder_traversal(std::vector<T>&output) {
if (this->left_child != nullptr) this->left_child->inorder_traversal(output);
output.push_back(this->data);
if (this->right_child != nullptr) this->right_child->inorder_traversal(output);
}
void preorder_traversal(std::vector<T>&output) {
output.push_back(this->data);
if (this->left_child != nullptr) this->left_child->preorder_traversal(output);
if (this->right_child != nullptr) this->right_child->preorder_traversal(output);
}
void postorder_traversal(std::vector<T>&output) {
if (this->left_child != nullptr) this->left_child->postorder_traversal(output);
if (this->right_child != nullptr) this->right_child->postorder_traversal(output);
output.push_back(this->data);
}
void traverse_and_output(std::ostream&out, std::function<void(std::vector<T>&)> traverse_function) {
std::vector<T> traverse_result;
traverse_function(traverse_result);
for (auto const&i: traverse_result)
std::cout << i << " ";
std::cout << std::endl;
}
private:
NodePtr left_child;
NodePtr right_child;
int balance_factor = 0; // 平衡因子
int depth = 0; // 树的深度(高度)
T data;
std::function<bool(T&, T&)> compare_function_;
};
int main() {
std::vector<int> origin_vector;
int temp;
while (std::cin >> temp) {
origin_vector.push_back(temp);
}
auto generator = origin_vector.cbegin();
BiSortNode<int>::NodePtr bi_sort_node{new BiSortNode<int>(*generator++)};
while (generator != origin_vector.cend()) {
bi_sort_node->insert(bi_sort_node, *generator++);
}
std::vector<int> traversal_result;
bi_sort_node->inorder_traversal(traversal_result);
std::cout << "为了便于验证,以下依次输出平衡二叉树的前序、中序、后序遍历结果:" << std::endl;
bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
bi_sort_node->preorder_traversal(output);
});
bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
bi_sort_node->inorder_traversal(output);
});
bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
bi_sort_node->postorder_traversal(output);
});
return 0;
}
// 输入:
// 98 77 94 67 59 60 56 68 95 98 32 39 32 17 5 5 8 19 40 41
// 输出:
// 为了便于验证,以下依次输出平衡二叉树的前序、中序、后序遍历结果:
// 67 39 17 5 5 8 32 19 32 59 41 40 56 60 94 77 68 98 95 98
// 5 5 8 17 19 32 32 39 40 41 56 59 60 67 68 77 94 95 98 98
// 5 8 5 19 32 32 17 40 56 41 60 59 39 68 77 95 98 98 94 67