// binaryTreeNode.h
//
// Created by Dell on 2021/6/9.
//
#ifndef CHAPTER11_BINARYTREENODE_H
#define CHAPTER11_BINARYTREENODE_H
#include "string"
#include "stack"
#include "queue"
#include "vector"
using namespace std;
template<class T>
struct binaryTreeNode
{
T element;
binaryTreeNode<T> *leftChild, *rightChild;
binaryTreeNode() {leftChild=rightChild=NULL;}
binaryTreeNode(const T& theElement){
element = theElement;
leftChild=rightChild=NULL;
}
binaryTreeNode(const T& theElement, binaryTreeNode<T>* theLeft, binaryTreeNode<T>*theRight):element(theElement), leftChild(theLeft), rightChild(theRight) {}
};
// 输出测试
template<class T>
void visit(binaryTreeNode<T>* x)
{
std::cout << x->element << " ";
}
template<class T>
void inOrder(binaryTreeNode<T>* x)
{
if(x!=NULL){
inOrder(x->leftChild);
visit(x);
inOrder(x->rightChild);
}
}
// Q25(1)
template<class T>
void postCopyTreeNode(binaryTreeNode<T>* sourceNode, binaryTreeNode<T>* targetNode)
{
if (sourceNode!=NULL){
if (sourceNode->leftChild!=NULL) {
targetNode->leftChild = new binaryTreeNode<T>();
preCopyTreeNode(sourceNode->leftChild, targetNode->leftChild);
}
if (sourceNode->rightChild!=NULL) {
targetNode->rightChild = new binaryTreeNode<T>();
preCopyTreeNode(sourceNode->rightChild, targetNode->rightChild);
}
targetNode->element = sourceNode->element;
}
}
// Q25(2)
template<class T>
void preCopyTreeNode(binaryTreeNode<T>* sourceNode, binaryTreeNode<T>* targetNode)
{
if (sourceNode!=NULL){
targetNode->element = sourceNode->element;
if (sourceNode->leftChild!=NULL) {
targetNode->leftChild = new binaryTreeNode<T>();
preCopyTreeNode(sourceNode->leftChild, targetNode->leftChild);
}
if (sourceNode->rightChild!=NULL) {
targetNode->rightChild = new binaryTreeNode<T>();
preCopyTreeNode(sourceNode->rightChild, targetNode->rightChild);
}
}
}
// Q26 后序的方法,这里应该可以把两个程序优化成一个,
template<class T>
void calculateGetNum(binaryTreeNode<T>* sourceNode, std::stack<int>& numStack)
{
if (sourceNode!=NULL){
calculateGetNum(sourceNode->leftChild, numStack);
calculateGetNum(sourceNode->rightChild, numStack);
int num1, num2;
if (sourceNode->element != "+" && sourceNode->element != "-" && sourceNode->element != "*" && sourceNode->element != "/"){
num1 = atoi(sourceNode->element.c_str());
numStack.push(num1);
} else{
num1 = numStack.top();
numStack.pop();
num2 = numStack.top();
numStack.pop();
if(sourceNode->element== "+")
numStack.push(num2 + num1);
else if(sourceNode->element == "-")
numStack.push(num2 - num1);
else if(sourceNode->element== "*")
numStack.push(num2 * num1);
else if(sourceNode->element == "/")
numStack.push(num2 / num1);
}
}
}
template<class T>
int calculateNum(binaryTreeNode<T>* sourceNode)
{
std::stack<int> numStack;
calculateGetNum(sourceNode, numStack);
return numStack.top();
}
// Q27 依然是递归
template<class T>
int getDepth(binaryTreeNode<T>* sourceNode){
if (sourceNode!=NULL){
int numLeft = getDepth(sourceNode->leftChild);
int numRight = getDepth(sourceNode->rightChild);
return numLeft > numRight ? numLeft+1 : numRight+1;
}
return 0;
}
// Q28 计算节点个数
template<class T>
int getNodeCount(binaryTreeNode<T>* sourceNode){
if (sourceNode!=NULL){
int numLeft = getNodeCount(sourceNode->leftChild);
int numRight = getNodeCount(sourceNode->rightChild);
return numLeft + numRight + 1;
}
return 0;
}
// Q29 节点最多的层数
template<class T>
int nodeMostLayer(binaryTreeNode<T>* sourceNode){
std::queue<binaryTreeNode<T>* > q;
int totalLayer = getDepth(sourceNode);
int *layerCounts = new int[totalLayer+1]{0}; // 没有第0层,全部初始化为0
if (sourceNode==NULL) return 0;
else layerCounts[1]=1; // 根节点一定是1个
int mostLayer=0, mostLayerCount=0, currentLayer=1;
binaryTreeNode<T> *currentNode = sourceNode;
while (currentNode != NULL){
if (currentNode->leftChild != NULL){
q.push(currentNode->leftChild);
++layerCounts[currentLayer+1]; // 更新下一层的个数
}
if (currentNode->rightChild != NULL){
q.push(currentNode->rightChild);
++layerCounts[currentLayer+1];
}
if (!q.empty()){
currentNode = q.front();
q.pop();
} else
currentNode = NULL;
--layerCounts[currentLayer]; // 这里已经减1了,所以下边要加1
if (layerCounts[currentLayer]==0) // 当前层遍历完成
++currentLayer; // 切换到下一层
else if (layerCounts[currentLayer] > mostLayerCount){ // 还在当前层
mostLayerCount = layerCounts[currentLayer] + 1;
mostLayer = currentLayer;
}
}
std::cout << "layer: " << mostLayer << " count: " << mostLayerCount << std::endl;
return mostLayer;
}
// Q30 将二叉树保存到栈中
template<class T>
void inVec(binaryTreeNode<T>* sourceNode, std::vector<T>& myVec){
if(sourceNode!=NULL){
inVec(sourceNode->leftChild, myVec);
myVec.push_back(sourceNode->element);
inVec(sourceNode->rightChild, myVec);
}
}
// Q31 将二叉树保存到栈中,因为使用了栈,所以输出顺序和入栈顺序相反
template<class T>
void preVec(binaryTreeNode<T>* sourceNode, std::vector<T>& myVec){
if(sourceNode!=NULL){
myVec.push_back(sourceNode->element);
preVec(sourceNode->leftChild, myVec);
preVec(sourceNode->rightChild, myVec);
}
}
// Q32 将二叉树保存到栈中
template<class T>
void postVec(binaryTreeNode<T>* sourceNode, std::vector<T>& myVec){
if(sourceNode!=NULL){
postVec(sourceNode->leftChild, myVec);
postVec(sourceNode->rightChild, myVec);
myVec.push_back(sourceNode->element);
}
}
// Q33需要用递归实现,且需要保证各个节点的数据各不相同,否则获取的二叉树不唯一
// 需要重新导入二叉树数据
//template<class T>
//void Q33Recursion(binaryTreeNode<T>* targetNode, vector<T>& inVec, stack<T>& preStack,int parentIndex, int grandParentIndex)
//{
// if (!preStack.empty()){
// T curElement = preStack.top();
//
// int currentIndex = 0;
// for(auto t : inVec){
// if (t == curElement)
// break;
// else
// ++currentIndex;
// }
// if (currentIndex<parentIndex){ // 在当前分支下
// targetNode->leftChild = new binaryTreeNode<T>(curElement);
// preStack.pop();
// Q33Recursion(targetNode->leftChild, inVec, preStack, currentIndex, parentIndex);
// }
// }
//
// if (!preStack.empty()){
// T curElement = preStack.top();
//
// int currentIndex = 0;
// for(auto t : inVec){
// if (t == curElement)
// break;
// else
// ++currentIndex;
// }
// if (currentIndex>parentIndex && currentIndex < grandParentIndex) { // 右节点
// targetNode->rightChild = new binaryTreeNode<T>(curElement);
// preStack.pop();
// Q33Recursion(targetNode->rightChild, inVec, preStack, currentIndex, parentIndex);
// }
// }
//}
//
//template<class T>
//binaryTreeNode<T>* getTreeFromPreAndInStack(binaryTreeNode<T>* sourceNode)
//{
// vector<T> MyPreVec, MyInVec;
// preVec(sourceNode, MyPreVec);
// inVec(sourceNode, MyInVec);
//
// stack<T> PreStack;
// for (int i = MyPreVec.size()-1;i >=0 ; --i)
// PreStack.push(MyPreVec[i]);
//
// T curElement = PreStack.top();
// PreStack.pop();
//
// int currentIndex = 0;
// for(auto t : MyInVec){
// if (t == curElement)
// break;
// else
// ++currentIndex;
// }
//
// auto targetNode = new binaryTreeNode<T>(curElement);
// Q33Recursion(targetNode, MyInVec, PreStack, currentIndex, MyInVec.size());
// return targetNode;
//}
// Q33
// 这个递归和上一个不成功的递归之间的区别就是是否把中序vector逐个拆开,如果不拆开就会导致上面的混乱
// 且引入很多不必要复杂的表示
template<class T>
binaryTreeNode<T>* Q33Recursion(vector<T>& inVec, stack<T>& preStack)
{
binaryTreeNode<T>* node = NULL;
if (!preStack.empty() && inVec.size() > 0)
{
T curElement = preStack.top();
int currentIndex = 0;
for(auto t : inVec){
if (t == curElement)
break;
else
++currentIndex;
}
if (currentIndex<inVec.size()) { // 当前vector中存在当前所需元素
// 构造分别对应当前的
vector<T> leftVec(inVec.begin(), inVec.begin()+currentIndex);
vector<T> rightVec(inVec.begin()+currentIndex+1, inVec.end());
preStack.pop();
node = new binaryTreeNode<T>(curElement);
node->leftChild = Q33Recursion(leftVec, preStack);
node->rightChild = Q33Recursion(rightVec, preStack);
}
}
return node;
}
template<class T>
binaryTreeNode<T>* getTreeFromPreAndInStack(binaryTreeNode<T>* sourceNode)
{
vector<T> MyPreVec, MyInVec;
preVec(sourceNode, MyPreVec);
inVec(sourceNode, MyInVec);
stack<T> PreStack;
for (int i = MyPreVec.size()-1;i >=0 ; --i)
PreStack.push(MyPreVec[i]);
binaryTreeNode<T>* p = Q33Recursion(MyInVec, PreStack);
return p;
}
// 每个运算。符必须有两个操作数,否则会有错误
binaryTreeNode<char>* getTreeFromPostOrder(string strVec)
{
stack<binaryTreeNode<char>*> NodeStack;
for(auto str : strVec){
auto temp = new binaryTreeNode<char>(str);
if (str == '+' || str == '-' || str == '*' || str == '/' ){ //单操作数或者双操作数
temp->rightChild = NodeStack.top();
NodeStack.pop();
if (!NodeStack.empty()){
temp->leftChild = NodeStack.top();
NodeStack.pop();
}
}
NodeStack.push(temp);
}
return NodeStack.top();
}
#endif //CHAPTER11_BINARYTREENODE_H
测试函数
// main.c
#include <iostream>
#include <string>
#include "include/binaryTreeNode.h"
using namespace std;
int main() {
// 手动实现二叉树的初始化
// auto* rootNode = new binaryTreeNode<string>("+");
// rootNode->leftChild = new binaryTreeNode<string>("+");
// rootNode->leftChild->leftChild = new binaryTreeNode<string>("*");
// rootNode->leftChild->rightChild = new binaryTreeNode<string>("12");
// rootNode->leftChild->leftChild->leftChild = new binaryTreeNode<string>("2");
// rootNode->leftChild->leftChild->rightChild = new binaryTreeNode<string>("4");
//
// rootNode->rightChild = new binaryTreeNode<string>("-");
// rootNode->rightChild->leftChild = new binaryTreeNode<string>("*");
// rootNode->rightChild->leftChild->leftChild = new binaryTreeNode<string>("8");
// rootNode->rightChild->leftChild->rightChild = new binaryTreeNode<string>("2");
// rootNode->rightChild->rightChild = new binaryTreeNode<string>("+");
// rootNode->rightChild->rightChild->leftChild = new binaryTreeNode<string>("6");
// rootNode->rightChild->rightChild->rightChild = new binaryTreeNode<string>("/");
// rootNode->rightChild->rightChild->rightChild->leftChild = new binaryTreeNode<string>("8");
// rootNode->rightChild->rightChild->rightChild->rightChild = new binaryTreeNode<string>("2");
auto* rootNode = new binaryTreeNode<string>("a");
rootNode->leftChild = new binaryTreeNode<string>("b");
rootNode->leftChild->leftChild = new binaryTreeNode<string>("c");
rootNode->leftChild->rightChild = new binaryTreeNode<string>("d");
rootNode->leftChild->leftChild->leftChild = new binaryTreeNode<string>("e");
rootNode->leftChild->leftChild->rightChild = new binaryTreeNode<string>("f");
rootNode->rightChild = new binaryTreeNode<string>("g");
rootNode->rightChild->leftChild = new binaryTreeNode<string>("h");
rootNode->rightChild->leftChild->leftChild = new binaryTreeNode<string>("i");
rootNode->rightChild->leftChild->rightChild = new binaryTreeNode<string>("j");
rootNode->rightChild->rightChild = new binaryTreeNode<string>("k");
rootNode->rightChild->rightChild->leftChild = new binaryTreeNode<string>("l");
rootNode->rightChild->rightChild->rightChild = new binaryTreeNode<string>("m");
rootNode->rightChild->rightChild->rightChild->leftChild = new binaryTreeNode<string>("n");
rootNode->rightChild->rightChild->rightChild->rightChild = new binaryTreeNode<string>("o");
// inOrder(rootNode); // 中序输出
// auto* preCopyNode = new binaryTreeNode<string>();
// auto* postCopyNode = new binaryTreeNode<string>();
// preCopyTreeNode(rootNode, preCopyNode);
rootNode->element = "fdfa";
// cout << endl << "pre"<< endl;
// inOrder(preCopyNode);
// postCopyTreeNode(rootNode, postCopyNode);
// cout << endl << "post"<< endl;
// inOrder(postCopyNode);
// cout << calculateNum(rootNode) << endl;
// cout << getDepth(rootNode) << endl;
// cout << getNodeCount(rootNode) << endl;
// nodeMostLayer(rootNode);
// vector<string> MyVec;
// preVec(rootNode, MyVec);
// cout << "preStack: ";
// for (auto v : MyVec)
// cout << v << " ";
// MyVec.clear();
// cout << endl;
//
// inVec(rootNode, MyVec);
// cout << "inStack: ";
// for (auto v : MyVec)
// cout << v << " ";
// MyVec.clear();
// auto targetNode = getTreeFromPreAndInStack(rootNode);
// vector<string> MyVec;
// preVec(rootNode, MyVec);
// for (auto v : MyVec)
// cout << v << " ";
// MyVec.clear();
// cout << endl;
// inOrder(rootNode);
// cout << endl;
// inOrder(targetNode);
auto cal = getTreeFromPostOrder("ba-xy++eb+ca**/");
inOrder(cal);
return 0;
}
// linkedBinaryTree.h
//
// Created by Dell on 2021/6/28.
//
#ifndef CHAPTER11_LINKEDBINARYTREE_H
#define CHAPTER11_LINKEDBINARYTREE_H
#include "binaryTree.h"
#include "binaryTreeNode.h"
#include "stack"
template<class T>
class linkedBinaryTree : public binaryTree<binaryTreeNode<T> > // 把节点作为元素的数据类型
{
public:
linkedBinaryTree() {root=NULL, treeSize=0;}
~linkedBinaryTree() {erase();}; // 这里为什么多一个分号
bool empty() const {return treeSize==0;}
int size() const {return treeSize;}
void preOrder(void (*theVisit)(binaryTreeNode<T>*)) {visit = theVisit, preOrder(root);}
void inOrder(void(*theVisit)(binaryTreeNode<T>*)) {visit = theVisit, inOrder(root);}
void postOrder(void(*theVisit)(binaryTreeNode<T>*)) {visit = theVisit, postOrder(root);}
void erase()
{
postOrder(dispose); // 用此函数对visit函数进行赋值
root = NULL;
treeSize = 0;
}
static void output(binaryTreeNode<T>* t) {std::cout << t->element << " "; }
void preOrderOutput() { preOrder(output), std::cout << std::endl;} // 传递函数指针,所以output不用指定参数,内部调用visit时会指定
void inOrderOutput() { inOrder(output), std::cout << std::endl;}
void postOrderOutput() { postOrder(output), std::cout << std::endl;}
int height() const { return height(root); }
int height(binaryTreeNode<T> *);
linkedBinaryTree(const linkedBinaryTree<T> &); // 复制构造函数
void initialize(binaryTreeNode<T> *); // 从一个已有根节点的二叉树结构的初始化此类对象
bool compare(const linkedBinaryTree<T> &);
void swapTrees();
// 中序输出
class forwardIterator{
public:
friend forwardIterator linkedBinaryTree<T>::begin();
explicit forwardIterator(binaryTreeNode<T>* theNode = NULL) { node = theNode; }
//解引用操作符
T& operator*() const { return node->element; }
T* operator->() const {return &node->element; }
// 相等验证
bool operator==(const forwardIterator& right) const { return node == right.node; }
bool operator!=(const forwardIterator& right) const { return node != right.node; }
// 单向递增
forwardIterator& operator++() {node=nodeQueue.front();nodeQueue.pop();return *this;}
forwardIterator operator++(int) {forwardIterator temp=node;node=nodeQueue.front();nodeQueue.pop();return temp;}
private:
binaryTreeNode<T>* node;
std::queue<binaryTreeNode<T>*> nodeQueue;
};
forwardIterator begin() {
forwardIterator temp;
getForwardIteratorQueue(temp.nodeQueue, root);
temp.nodeQueue.push(NULL); // 用于判断是否到尾
temp.node = temp.nodeQueue.front();
temp.nodeQueue.pop();
return temp;
}
forwardIterator end() const {return forwardIterator();}
private:
binaryTreeNode<T> *root;
int treeSize;
// 函数指针,用来访问节点元素,可以对这个函数指针进行赋值
// 那么就会将赋值的指针的函数的功能传递过来,所以visit本质是一个指针变量
// static函数是类的所用对象共有,只能修改static成员变量
static void (*visit)(binaryTreeNode<T>*);
void preOrder(binaryTreeNode<T> *);
void inOrder(binaryTreeNode<T> *);
void postOrder(binaryTreeNode<T> *);
static void dispose(binaryTreeNode<T>* t) { delete t;}
void copyConstructor(binaryTreeNode<T>* srcNode, binaryTreeNode<T>* &targetNode);
bool compare(const binaryTreeNode<T>* firstNode, const binaryTreeNode<T>* secondNode);
void swapTrees(binaryTreeNode<T>* &firstNode, binaryTreeNode<T>* &secondNode);
void getForwardIteratorQueue(std::queue<binaryTreeNode<T>*> &myQueue, binaryTreeNode<T>* x);
};
// 这里很重要,由于visit是函数指针,本质是一个普通变量
// 而且又是一个static变量,所以需要在类外进行初始化
template<class T>
void (*linkedBinaryTree<T>::visit)(binaryTreeNode<T>*) = nullptr;
template<class T>
int linkedBinaryTree<T>::height(binaryTreeNode<T> *t) {
if (t==NULL)
return 0;
int hl = height(t->leftChild);
int hr = height(t->rightChild);
if (hl > hr) // 还要加上本层的高度
return ++hl;
else
return ++hr;
}
template<class T>
linkedBinaryTree<T>::linkedBinaryTree(const linkedBinaryTree<T> &srcTree) {
copyConstructor(srcTree.root, this->root);
this->treeSize = srcTree.treeSize;
}
template<class T>
void linkedBinaryTree<T>::preOrder(binaryTreeNode<T> *t) {
if (t != NULL){
visit(t);
preOrder(t->leftChild);
preOrder(t->rightChild);
}
}
template<class T>
void linkedBinaryTree<T>::inOrder(binaryTreeNode<T> *t) {
if (t != NULL){
inOrder(t->leftChild);
visit(t);
inOrder(t->rightChild);
}
}
template<class T>
void linkedBinaryTree<T>::postOrder(binaryTreeNode<T> *t) {
if (t != NULL){
postOrder(t->leftChild);
postOrder(t->rightChild);
visit(t);
}
}
// 注意这里指针的引用
template<class T>
void linkedBinaryTree<T>::copyConstructor(binaryTreeNode<T>* srcNode, binaryTreeNode<T>* &targetNode) {
if (srcNode != NULL){
++treeSize;
targetNode = new binaryTreeNode<T>(srcNode->element);
copyConstructor(srcNode->leftChild, targetNode->leftChild);
copyConstructor(srcNode->rightChild, targetNode->rightChild);
}
}
template<class T>
void linkedBinaryTree<T>::initialize(binaryTreeNode<T> *srcNode) {
this->treeSize=0;
copyConstructor(srcNode, root);
}
template<class T>
bool linkedBinaryTree<T>::compare(const linkedBinaryTree<T> &theTree) {
if (size()!=theTree.size())
return false;
return compare(root, theTree.root);
}
template<class T>
bool linkedBinaryTree<T>::compare(const binaryTreeNode<T> *firstNode, const binaryTreeNode<T> *secondNode) {
if (firstNode==NULL && secondNode==NULL)
return true;
if ((firstNode==NULL && secondNode!=NULL) || (firstNode!=NULL && secondNode==NULL))
return false;
// 全都有值
if (firstNode->element != secondNode->element)
return false;
else // 在元素值相等的前提下
return compare(firstNode->leftChild, secondNode->leftChild) && compare(firstNode->rightChild, secondNode->rightChild);
}
template<class T>
void linkedBinaryTree<T>::swapTrees() {
swapTrees(root->leftChild, root->rightChild);
}
template<class T>
void linkedBinaryTree<T>::swapTrees(binaryTreeNode<T>* &firstNode, binaryTreeNode<T>* &secondNode) {
if (firstNode!=NULL && secondNode!=NULL) {
binaryTreeNode<T>* temp;
temp = firstNode;
firstNode = secondNode;
secondNode = temp;
swapTrees(firstNode->leftChild, firstNode->rightChild);
swapTrees(secondNode->leftChild, secondNode->rightChild);
}
}
template<class T>
void linkedBinaryTree<T>::getForwardIteratorQueue(std::queue<binaryTreeNode<T> *> &myQueue, binaryTreeNode<T> *x) {
if(x!=NULL){
getForwardIteratorQueue(myQueue, x->leftChild);
myQueue.push(x);
getForwardIteratorQueue(myQueue, x->rightChild);
}
}
#endif //CHAPTER11_LINKEDBINARYTREE_H