C++ 二叉树(建立、销毁、前中后序遍历和层次遍历,寻找双亲结点等)

(1)结构体和类定义

struct BTreeNode {T data;BTreeNode* left, * right;BTreeNode() :data(0), left(nullptr), right(nullptr) {}BTreeNode(T val, BTreeNode<T>* leftChild = nullptr, BTreeNode<T>* rightChild = nullptr):data(val), left(leftChild), right(rightChild) {}};template<class T>
class BTree {
public:BTree() :root(nullptr) {}										      // 构造函数BTree(string str);                                                    // 重载void createTree(BTreeNode<T>*& bt, string str);                       // 创建二次树~BTree();														      // 析构函数bool IsEmpty();													      // 判二叉树空否?int Size(BTreeNode<T>* cur);                                          // 计算结点个数int getSize();                                                        // 获取结点个数BTreeNode<T>* getData(T& item, BTreeNode<T>* cur);	                  // 取得结点数据bool Find(T& item);		                                              // 判断item是否在树中int Height(BTreeNode<T>* bt);                                         // 求树高度int getHeight();                                                      // 获取树高度BTreeNode<T>* getRoot();	                                          // 取根void preOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);          // 前序遍历void inOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);		      // 中序遍历void postOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);         // 后序遍历void levelOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);        // 层序遍历vector<T> preOrder();						                          // 调用前序遍历,返回vectorvector<T> inOrder();											      // 调用中序遍历,返回vectorvector<T> postOrder();											      // 调用后序遍历,返回vectorvector<T> levelOrder();                                               // 调用层序遍历,返回vectorvoid CopyTree(BTreeNode<T>* root, BTreeNode<T>*& copyRoot);           // 二叉树复制void Copy(BTreeNode<T>*& copyRoot);                                   // 调用二叉树复制void destroyCopyTree(BTreeNode<T>*& copyRoot);                        // 销毁复制二叉树BTreeNode<T>* FindParent(BTreeNode<T>* root, BTreeNode<T>* node);     // 寻找双亲BTreeNode<T>* LeftChild(BTreeNode<T>* node) {                         //求结点 node 的左孩子return (node != nullptr) ? node->left : nullptr;}BTreeNode<T>* RightChild(BTreeNode<T>* node) {                        //求结点 node 的右孩子return (node != nullptr) ? node->right : nullptr;}protected:BTreeNode<T>* root;void destroyTree(BTreeNode<T>* node);                                // 销毁二叉树
};

(2)创建二叉树

template<class T>
BTree<T>::BTree(string str) {createTree(root, str);cout << "报告:创建一颗二叉树,完成!!!" << endl;
}template<class T>
void BTree<T>::createTree(BTreeNode<T>*& bt, string str) {static int i = 0;char ch = ' ';ch = str[i++];if (ch == '#') bt = nullptr;else {bt = new BTreeNode<T>(ch);createTree(bt->left, str);createTree(bt->right, str);}
};

(3)前中后序遍历和层序遍历

// 前序遍历
template<class T>
void BTree<T>::preOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;vec.push_back(cur->data);           // 中preOrderTraversal(cur->left, vec);  // 左preOrderTraversal(cur->right, vec); // 右
}// 调用前序遍历,返回vector
template<class T>
vector<T> BTree<T>::preOrder() {cout << "获取前序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;preOrderTraversal(root, resVec);return resVec;
}// 中序遍历
template<class T>
void BTree<T>::inOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;inOrderTraversal(cur->left, vec);  // 左vec.push_back(cur->data);          // 中inOrderTraversal(cur->right, vec); // 右
}// 调用中序遍历,返回vector
template<class T>
vector<T> BTree<T>::inOrder() {cout << "获取中序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;inOrderTraversal(root, resVec);return resVec;
}// 后序遍历
template<class T>
void BTree<T>::postOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;postOrderTraversal(cur->left, vec);  // 左postOrderTraversal(cur->right, vec); // 右vec.push_back(cur->data);            // 中
}// 调用后序遍历,返回vector
template<class T>
vector<T> BTree<T>::postOrder() {cout << "获取后序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;postOrderTraversal(root, resVec);return resVec;
}// 层序遍历
template<class T>
void BTree<T>::levelOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr) return;queue<BTreeNode<T>*> Queue;BTreeNode<T>* p;Queue.push(cur); // 根结点入队列while (!Queue.empty()) {p = Queue.front();//cout << p->data << " ";//输出出队结点的数据vec.push_back(p->data);Queue.pop();if (p->left != nullptr) {Queue.push(p->left);}if (p->right != nullptr) {Queue.push(p->right);}}
}// 调用层序遍历,返回vector
template<class T>
vector<T> BTree<T>::levelOrder() {cout << "获取层序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;levelOrderTraversal(root, resVec);return resVec;
}

(4)复制二叉树

template<class T>
void BTree<T>::CopyTree(BTreeNode<T>* root, BTreeNode<T>*& copyRoot) {if (!root) {copyRoot = nullptr;}else {copyRoot = new BTreeNode<T>;copyRoot->data = root->data;           //复制根节点CopyTree(root->left, copyRoot->left);  //递归复制左子树CopyTree(root->right, copyRoot->right);//递归复制左子树}
}template<class T>
void BTree<T>::Copy(BTreeNode<T>*& copyRoot) {CopyTree(root, copyRoot);
}

(5)销毁二叉树

template<class T>
void BTree<T>::destroyCopyTree(BTreeNode<T>*& copyRoot) {destroyTree(copyRoot);cout << "报告,复制二叉树已销毁完毕!!!" << endl;
}// 销毁二叉树 
template<class T>
void BTree<T>::destroyTree(BTreeNode<T>* bt) {// 后序遍历删除根为subTree的子树;if (bt != nullptr) {destroyTree(bt->left);    //删除左子树destroyTree(bt->right);   //删除右子树delete bt; 			      //删除根结点}
}

(6)析构函数

// 析构函数
template<class T>
BTree<T>::~BTree<T>() {//cout << "调用析构函数" << endl;destroyTree(root);cout << "报告,这棵树已经销毁完毕!!!" << endl;
}

(7)求树的高度

// 求树高度
template<class T>
int BTree<T>::Height(BTreeNode<T>* bt) {if (bt == nullptr) return 0;else {int leftH = Height(bt->left);int rightH = Height(bt->right);return (leftH > rightH) ? leftH + 1 : rightH + 1;}
}// 获取树高度
template<class T>
int BTree<T>::getHeight() {return Height(root);
}

(8)获取结点,判断其是否在二叉树中

// 取得结点数据
template<class T>
BTreeNode<T>* BTree<T>::getData(T& item, BTreeNode<T>* cur) {if (cur == nullptr) return nullptr;if (cur->data == item) return cur;return getData(item, cur->left) != nullptr ? getData(item, cur->left) : getData(item, cur->right);
}// 判断item是否在树中
template<class T>
bool BTree<T>::Find(T& item) {if (this->getData(item, root) == nullptr) return false;else return true;

(9)计算结点个数和获取结点个数

// 计算结点个数
template<class T>
int BTree<T>::Size(BTreeNode<T>* cur) {if (cur == nullptr)return 0;elsereturn 1 + Size(cur->left) + Size(cur->right);
}// 获取结点个数
template<class T>
int BTree<T>::getSize() {return Size(root);
}

(10)二叉树判空

// 判二叉树空否?
template<class T>
bool BTree<T>::IsEmpty() {return (root == nullptr) ? true : false;
}

(11)获取根结点

// 获取根 
template<class T>
BTreeNode<T>* BTree<T>::getRoot() {if (!root) return nullptr;else {return this->root;}
}

源代码:

btree.h

#pragma once
#include <iostream>
#include <vector>
#include <queue>
using namespace std;template<class T>
struct BTreeNode {T data;BTreeNode* left, * right;BTreeNode() :data(0), left(nullptr), right(nullptr) {}BTreeNode(T val, BTreeNode<T>* leftChild = nullptr, BTreeNode<T>* rightChild = nullptr):data(val), left(leftChild), right(rightChild) {}};template<class T>
class BTree {
public:BTree() :root(nullptr) {}										      // 构造函数BTree(string str);                                                    // 重载void createTree(BTreeNode<T>*& bt, string str);                       // 创建二次树~BTree();														      // 析构函数bool IsEmpty();													      // 判二叉树空否?int Size(BTreeNode<T>* cur);                                          // 计算结点个数int getSize();                                                        // 获取结点个数BTreeNode<T>* getData(T& item, BTreeNode<T>* cur);	                  // 取得结点数据bool Find(T& item);		                                              // 判断item是否在树中int Height(BTreeNode<T>* bt);                                         // 求树高度int getHeight();                                                      // 获取树高度BTreeNode<T>* getRoot();	                                          // 取根void preOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);          // 前序遍历void inOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);		      // 中序遍历void postOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);         // 后序遍历void levelOrderTraversal(BTreeNode<T>* cur, vector<int>& vec);        // 层序遍历vector<T> preOrder();						                          // 调用前序遍历,返回vectorvector<T> inOrder();											      // 调用中序遍历,返回vectorvector<T> postOrder();											      // 调用后序遍历,返回vectorvector<T> levelOrder();                                               // 调用层序遍历,返回vectorvoid CopyTree(BTreeNode<T>* root, BTreeNode<T>*& copyRoot);           // 二叉树复制void Copy(BTreeNode<T>*& copyRoot);                                   // 调用二叉树复制void destroyCopyTree(BTreeNode<T>*& copyRoot);                        // 销毁复制二叉树BTreeNode<T>* FindParent(BTreeNode<T>* root, BTreeNode<T>* node);     // 寻找双亲BTreeNode<T>* LeftChild(BTreeNode<T>* node) {                         //求结点 node 的左孩子return (node != nullptr) ? node->left : nullptr;}BTreeNode<T>* RightChild(BTreeNode<T>* node) {                        //求结点 node 的右孩子return (node != nullptr) ? node->right : nullptr;}protected:BTreeNode<T>* root;void destroyTree(BTreeNode<T>* node);                                // 销毁二叉树
};

btree.cpp

// 每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!
// 1.确定递归函数的参数的返回值
// 2.确定终止条件
// 3.确定单层递归的逻辑#include "btree.h"template<class T>
BTree<T>::BTree(string str) {createTree(root, str);cout << "报告:创建一颗二叉树,完成!!!" << endl;
}template<class T>
void BTree<T>::createTree(BTreeNode<T>*& bt, string str) {static int i = 0;char ch = ' ';ch = str[i++];if (ch == '#') bt = nullptr;else {bt = new BTreeNode<T>(ch);createTree(bt->left, str);createTree(bt->right, str);}
};// 判二叉树空否?
template<class T>
bool BTree<T>::IsEmpty() {return (root == nullptr) ? true : false;
}// 计算结点个数
template<class T>
int BTree<T>::Size(BTreeNode<T>* cur) {if (cur == nullptr)return 0;elsereturn 1 + Size(cur->left) + Size(cur->right);
}// 获取结点个数
template<class T>
int BTree<T>::getSize() {return Size(root);
}// 取得结点数据
template<class T>
BTreeNode<T>* BTree<T>::getData(T& item, BTreeNode<T>* cur) {if (cur == nullptr) return nullptr;if (cur->data == item) return cur;return getData(item, cur->left) != nullptr ? getData(item, cur->left) : getData(item, cur->right);
}// 判断item是否在树中
template<class T>
bool BTree<T>::Find(T& item) {if (this->getData(item, root) == nullptr) return false;else return true;
}// 求树高度
template<class T>
int BTree<T>::Height(BTreeNode<T>* bt) {if (bt == nullptr) return 0;else {int leftH = Height(bt->left);int rightH = Height(bt->right);return (leftH > rightH) ? leftH + 1 : rightH + 1;}
}// 获取树高度
template<class T>
int BTree<T>::getHeight() {return Height(root);
}// 获取根 
template<class T>
BTreeNode<T>* BTree<T>::getRoot() {if (!root) return nullptr;else {return this->root;}
}// 析构函数
template<class T>
BTree<T>::~BTree<T>() {//cout << "调用析构函数" << endl;destroyTree(root);cout << "报告,这棵树已经销毁完毕!!!" << endl;
}// 销毁二叉树 
template<class T>
void BTree<T>::destroyTree(BTreeNode<T>* bt) {// 后序遍历删除根为subTree的子树;if (bt != nullptr) {destroyTree(bt->left);    //删除左子树destroyTree(bt->right);   //删除右子树delete bt; 			      //删除根结点}
}// 前序遍历
template<class T>
void BTree<T>::preOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;vec.push_back(cur->data);           // 中preOrderTraversal(cur->left, vec);  // 左preOrderTraversal(cur->right, vec); // 右
}// 调用前序遍历,返回vector
template<class T>
vector<T> BTree<T>::preOrder() {cout << "获取前序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;preOrderTraversal(root, resVec);return resVec;
}// 中序遍历
template<class T>
void BTree<T>::inOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;inOrderTraversal(cur->left, vec);  // 左vec.push_back(cur->data);          // 中inOrderTraversal(cur->right, vec); // 右
}// 调用中序遍历,返回vector
template<class T>
vector<T> BTree<T>::inOrder() {cout << "获取中序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;inOrderTraversal(root, resVec);return resVec;
}// 后序遍历
template<class T>
void BTree<T>::postOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr)return;postOrderTraversal(cur->left, vec);  // 左postOrderTraversal(cur->right, vec); // 右vec.push_back(cur->data);            // 中
}// 调用后序遍历,返回vector
template<class T>
vector<T> BTree<T>::postOrder() {cout << "获取后序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;postOrderTraversal(root, resVec);return resVec;
}// 层序遍历
template<class T>
void BTree<T>::levelOrderTraversal(BTreeNode<T>* cur, vector<int>& vec) {if (cur == nullptr) return;queue<BTreeNode<T>*> Queue;BTreeNode<T>* p;Queue.push(cur); // 根结点入队列while (!Queue.empty()) {p = Queue.front();//cout << p->data << " ";//输出出队结点的数据vec.push_back(p->data);Queue.pop();if (p->left != nullptr) {Queue.push(p->left);}if (p->right != nullptr) {Queue.push(p->right);}}
}// 调用层序遍历,返回vector
template<class T>
vector<T> BTree<T>::levelOrder() {cout << "获取层序遍历数组...." << endl;cout << ">>>>";vector<T> resVec;levelOrderTraversal(root, resVec);return resVec;
}template<class T>
void BTree<T>::CopyTree(BTreeNode<T>* root, BTreeNode<T>*& copyRoot) {if (!root) {copyRoot = nullptr;}else {copyRoot = new BTreeNode<T>;copyRoot->data = root->data;           //复制根节点CopyTree(root->left, copyRoot->left);  //递归复制左子树CopyTree(root->right, copyRoot->right);//递归复制左子树}
}template<class T>
void BTree<T>::Copy(BTreeNode<T>*& copyRoot) {CopyTree(root, copyRoot);
}template<class T>
void BTree<T>::destroyCopyTree(BTreeNode<T>*& copyRoot) {destroyTree(copyRoot);cout << "报告,复制二叉树已销毁完毕!!!" << endl;
}template<class T>
BTreeNode<T>* BTree<T>::FindParent(BTreeNode<T>* root, BTreeNode<T>* node) {if (root == nullptr) return nullptr;if (root->left == node || root->right == node)return root;	     //找到, 返回父结点地址BTreeNode <T>* p;if ((p = FindParent(root->left, node)) != nullptr)return p;	         //递归在左子树中搜索else return FindParent(root->right, node);
}

test.cpp

#include "btree.h"
#include "btree.cpp"
//#include <iostream>
//using namespace std;
int main() {cout << "-------------------------Start--------------------------" << endl;cout << "---------------------创建原始二叉树---------------------" << endl;string str = "ABD#G##E##CF###";BTree<int>* T = new BTree<int>(str);BTreeNode<int>* root = T->getRoot();cout << "这棵树有 " << T->getSize() << " 个结点" << endl;int zifu = 'G';if (T->Find(zifu)) {cout << "这棵树有 " << (char)zifu << " 结点" << endl;}else {cout << "这棵树无 " << (char)zifu << " 结点" << endl;}BTreeNode<int>* node = T->getData(zifu, root);if (node) {cout << (char)node->data << endl;BTreeNode<int>* nodeParent = T->FindParent(root, node);if (!nodeParent) {cout << "找不到父亲结点" << endl;}else {cout << "结点 " << (char)zifu << " 的父亲结点是: " << (char)nodeParent->data << " 结点" << endl;if (nodeParent->left) cout << "我的左孩子是: " << (char)nodeParent->left->data << endl;else cout << "我没有左孩子..." << endl;if (nodeParent->right) cout << "我的右孩子是: " << (char)nodeParent->right->data << endl;else cout << "我没有右孩子..." << endl;}}cout << "这棵树的高度为: " << T->getHeight() << endl;vector<int> vec = T->preOrder();for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();vec = T->inOrder();for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();vec = T->postOrder();for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();vec = T->levelOrder();for (auto i : vec) {cout << (char)i;}cout << endl;cout << "-----------------------复制二叉树-----------------------" << endl;// 复制二叉树//vector<int> vec;//BTreeNode<int>* root = T->getRoot();BTreeNode<int>* copyRoot = new BTreeNode<int>;//T->Copy(copyRoot);          // 方法一T->CopyTree(root, copyRoot);  // 方法二vec.clear();cout << "获取前序遍历数组...." << endl;cout << ">>>>";T->preOrderTraversal(copyRoot, vec);for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();cout << "获取中序遍历数组...." << endl;cout << ">>>>";T->inOrderTraversal(copyRoot, vec);for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();cout << "获取后序遍历数组...." << endl;cout << ">>>>";T->postOrderTraversal(copyRoot, vec);for (auto i : vec) {cout << (char)i;}cout << endl;vec.clear();cout << "获取层序遍历数组...." << endl;cout << ">>>>";T->levelOrderTraversal(copyRoot, vec);for (auto i : vec) {cout << (char)i;}cout << endl;cout << "---------------------销毁复制二叉树---------------------" << endl;T->destroyCopyTree(copyRoot);cout << "---------------------销毁原始二叉树---------------------" << endl;T->~BTree();cout << "--------------------------End---------------------------" << endl;return 0;
}

>>测试结果 

-------------------------Start--------------------------
---------------------创建原始二叉树---------------------
报告:创建一颗二叉树,完成!!!
这棵树有 7 个结点
这棵树有 G 结点
G
结点 G 的父亲结点是: D 结点
我没有左孩子...
我的右孩子是: G
这棵树的高度为: 4
获取前序遍历数组....
>>>>ABDGECF
获取中序遍历数组....
>>>>DGBEAFC
获取后序遍历数组....
>>>>GDEBFCA
获取层序遍历数组....
>>>>ABCDEFG
-----------------------复制二叉树-----------------------
获取前序遍历数组....
>>>>ABDGECF
获取中序遍历数组....
>>>>DGBEAFC
获取后序遍历数组....
>>>>GDEBFCA
获取层序遍历数组....
>>>>ABCDEFG
---------------------销毁复制二叉树---------------------
报告,复制二叉树已销毁完毕!!!
---------------------销毁原始二叉树---------------------
报告,这棵树已经销毁完毕!!!
--------------------------End---------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/67168.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十九、docker学习-Dockerfile

Dockerfile 官网地址 https://docs.docker.com/engine/reference/builder/Dockerfile其实就是我们用来构建Docker镜像的源码&#xff0c;当然这不是所谓的编程源码&#xff0c;而是一些命令的集合&#xff0c;只要理解它的逻辑和语法格式&#xff0c;就可以很容易的编写Docke…

【佳佳怪文献分享】安全人机交互的学习责任分配与自动驾驶应用

标题&#xff1a;Learning Responsibility Allocations for Safe Human-Robot Interaction with Applications to Autonomous Driving 作者&#xff1a;Ryan K. Cosner, Yuxiao Chen, Karen Leung, and Marco Pavone 来源&#xff1a;2023 IEEE International Conference on …

JavaEE初阶:多线程 - 编程

1.认识线程 我们在之前认识了什么是多进程&#xff0c;今天我们来了解线程。 一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行 着多份代码. 引入进程这个概念&#xff0c;主要是为了解决并发编程这样的…

APP外包开发的iOS开发语言

学习iOS开发需要掌握Swift编程语言和相关的开发工具、框架和技术。而学习iOS开发需要时间和耐心&#xff0c;尤其是对于初学者。通过坚持不懈的努力&#xff0c;您可以逐步掌握iOS开发技能&#xff0c;构建出功能丰富、优质的移动应用。今天和大家分享学习iOS开发的一些建议方法…

【广州华锐视点】AR电力职业技能培训系统让技能学习更“智慧”

随着科技的发展&#xff0c;教育方式也在不断地进步和创新。其中&#xff0c;增强现实(AR)技术的出现&#xff0c;为教育领域带来了全新的可能。AR电力职业技能培训系统就是这种创新教学方法的完美实践&#xff0c;它将虚拟与现实相结合&#xff0c;为学生提供了一个沉浸式的学…

JavaScript版本ES5/ES6及后续版本

JavaScript简史 1995&#xff1a; Brendan Eich在短短10天内创建了JavaScript的第一个版本。它被称为摩卡&#xff0c;但已经具备了现代JavaScript的许多基本特性! 1996&#xff1a; 为了吸引Java开发人员&#xff0c;Mocha先是更改为LiveScript&#xff0c;然后又更改为Ja…

UI设计师个人工作感悟5篇

UI设计师个人工作感悟一 工作一年了&#xff0c;结合我自身谈谈UI设计的重要性。现在主流的论坛建站程序有两种 Phpwind 和Discuz(Phpwind被阿里巴巴收购 Discuz被腾讯收购这两个论坛程序都是开源免费的)&#xff0c;利用这两种程序我都分别建立过论坛&#xff0c;我第一次用的…

R语言APSIM模型高级应用及批量模拟

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

【Spring专题】Spring之底层架构核心概念解析

目录 前言前置知识课程内容一、BeanDefinition&#xff1a;图纸二、BeanDefinitionReader&#xff1a;图纸注册器——Spring工厂基础设施之一2.1 AnnotatedBeanDefinitionReader2.2 XmlBeanDefinitionReader2.3 ClassPathBeanDefinitionScanner基本介绍总结使用示例 三、BeanFa…

移动端预览指定链接的pdf文件流

场景 直接展示外部系统返回的获取文件流时出现了跨域问题&#xff1a; 解决办法 1. 外部系统返回的请求头中调整&#xff08;但是其他系统不会给你改的&#xff09; 2. 我们系统后台获取文件流并转为新的文件流提供给前端 /** 获取传入url文件流 */ GetMapping("/get…

一百五十二、Kettle——Kettle9.3.0本地连接Hive3.1.2(踩坑,亲测有效)

一、目的 由于先前使用的kettle8.2版本在Linux上安装后&#xff0c;创建共享资源库点击connect时页面为空&#xff0c;后来采用如下方法&#xff0c;在/opt/install/data-integration/ui/menubar.xul文件里添加如下代码 <menuitem id"file-openZiyuanku" label&…

聊聊RedisTemplate的各种序列化器

[版权申明] 非商业目的注明出处可自由转载 出自&#xff1a;shusheng007 文章目录 概述序列化器作用和原理JDK 序列化方式多一点 String 序列化方式JSON 序列化方式 总结源码 概述 在SpringBoot中使用redis基本上都是通过Spring Data Redis&#xff0c;那就不得不说RedisTempl…