1.0 你怎么对二叉树进行遍历,你就可以使用这种遍历方式来创建二叉树。
因此二叉树的创建方式有很多种,我选择的是层次创建(与其相对应的是层次遍历,
也叫广度优先遍历)。
2.0 二叉树的销毁也可以使用其特定的遍历方式进行销毁。
3.0 因为层次遍历的过程很适合队列这种结构,所以可以使用queue来实现该遍历过程。
代码:
/*
(1)根据遍历的方式创建二叉树,你打算怎么遍历就怎么创建。
(2)使用堆栈存储二叉树,并使用先序遍历。
(3) 在插入的时候你怎么分插在左节点还是右节点?不分的话,如何插入?
(4) 利用数组常见二叉树,用标识符分左右
*/
#pragma once
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
// 二叉树结点
template <typename T>
class BinTreeNode {
public:
T data;
BinTreeNode<T>* left;
BinTreeNode<T>* right;
BinTreeNode(T data_)
:data{data_},left{nullptr},right{nullptr}
{}
};
template <typename T>
class BinTree
{
typedef BinTreeNode<T> node;
private:
protected:
node* root;
void PreorderTraversal_(node *root);
void PreoderTraversalByStack_(node* root);
void MiddleTraversal_(node* root);
void MiddleTraversalByStack_(node* root);
void PostTraversal_(node* root);
void PostTraversalByStack_(node* root);
void NodeSize_(node* rootTemp, size_t& size);
node* Find_(node* root, const T& x);
size_t LeafNodeSize_(node*root);
size_t Height_(node* root);
size_t NodeSizeKth_(node* root, size_t k);
public:
BinTree(T* dataArr_, size_t dataArrLength, const T& nullMark, size_t index = 0);
~BinTree();
/// 错误的地方,这里没有传递index 的引用,卧槽。
// 使用数组初始化二叉树:
//创建一棵二叉树------
node* CreateBinTree(T* dataArr_, size_t dataArrLength, const T& nullMark, size_t& index);
// 传过去一个root 是为了不修改 原本对象的root;
// 在这里调用根,来隐藏根节点。
void PreoderTraversal();
void PreoderTraversalByStack();
void MiddleTraversal()
{
MiddleTraversal_(root);
}
void MiddleTraversalByStack()
{
MiddleTraversalByStack_(root);
}
void PostTraversal()
{
PostTraversal_(root);
}
void PostTraversalByStack()
{
PostTraversalByStack_(root);
}
//层序遍历
void FloorOrder();
// 使用后续遍历,析构树
void DestroyTree(node* root);
// 树的节点个数
size_t NodeSize();
//求叶子节点的个数
size_t LeafNodesize();
//判断二叉树是否为完全二叉树
bool isCompleteTree();
//查找一个节点是否在一棵二叉树中
node* Find(const T& x);
// 求二叉树的高度:
size_t Height();
// 求第k层的节点个数:
size_t NodeSizeKth(size_t k);
// 寻找路径:
void FindPath();
};
// 构造
template<typename T>
BinTree<T>::BinTree(T * dataArr_, size_t dataArrLength, const T & nullMark, size_t index)
{
root = CreateBinTree(dataArr_, dataArrLength, nullMark, index);
}
// 析构
template<typename T>
BinTree<T>::~BinTree()
{
DestroyTree(root);
}
template<typename T>
BinTreeNode<T>* BinTree<T>::CreateBinTree(T * dataArr_, size_t dataArrLength, const T & nullMark, size_t & index)
{
BinTreeNode<T>* root = nullptr;
if (dataArr_[index] != nullMark)
{
root = new BinTreeNode<T>(dataArr_[index]);
root->left = CreateBinTree(dataArr_, dataArrLength, nullMark, ++index);
root->right = CreateBinTree(dataArr_, dataArrLength, nullMark, ++index);
}
return root;
}
template<typename T>
void BinTree<T>::DestroyTree(node * root)
{
if (root == nullptr)
return;
DestroyTree(root->left);
DestroyTree(root->right);
delete root;
}
// 先序-递归
template<typename T>
void BinTree<T>::PreoderTraversal()
{
PreorderTraversal_(root);
}
template<typename T>
void BinTree<T>::PreorderTraversal_(node * root)
{
if (root == nullptr)
return;
std::cout << root->data << " ";
PreorderTraversal_(root->left);
PreorderTraversal_(root->right);
}
// 先序-堆栈
template<typename T>
void BinTree<T>::PreoderTraversalByStack()
{
PreoderTraversalByStack_(root);
}
template<typename T>
void BinTree<T>::MiddleTraversalByStack_(node * root)
{
node* currentNode = root;
stack<node*>s;
while (currentNode || !s.empty())
{
while (currentNode)
{
s.push(currentNode);
currentNode = currentNode->left;
}
node* top = s.top();
cout << top->data << " ";
s.pop();
currentNode = top->right;
}
cout << endl;
}
template<typename T>
void BinTree<T>::MiddleTraversal_(node * root)
{
if (root == nullptr)
return;
MiddleTraversal_(root->left);
cout << root->data << " ";
MiddleTraversal_(root->right);
}
template<typename T>
void BinTree<T>::PostTraversal_(node * root)
{
if (root == nullptr)
return;
PostTraversal_(root->left);
PostTraversal_(root->right);
cout << root->data << " ";
}
template<typename T>
void BinTree<T>::PostTraversalByStack_(node * root)
{
node* currentNode = root;
node*previous = nullptr;
stack<node*>s;
while (currentNode || !s.empty())
{
while (currentNode)
{
s.push(currentNode);
currentNode = currentNode->left;
}
node* top = s.top();
if (top->right == NULL || top->right == previous)
{
cout << top->data << " ";
s.pop();
previous = top;
}
else
{
currentNode = top->right;
}
}
cout << endl;
}
template<typename T>
void BinTree<T>::FloorOrder()
{
queue<node *>q;
if (root)
q.push(root);
while (!q.empty())
{
node* front = q.front();
cout << front->data << " ";
q.pop();
if (front->left)
q.push(front->left);
if (front->right)
q.push(front->right);
}
cout << endl;
}
template<typename T>
void BinTree<T>::PreoderTraversalByStack_(node * root)
{
node* currentNode = root;
std::stack<node*>s;
while (currentNode || !s.empty())
{
while (currentNode)
{
std::cout << currentNode->data << " ";
s.push(currentNode);
currentNode = currentNode->left;
}
node* top = s.top();
s.pop();
//子问题
currentNode = top->right;
}
std::cout << std::endl;
}
template<typename T>
size_t BinTree<T>::NodeSize()
{
size_t size = 0;
NodeSize_(root, size);
return size;
}
template<typename T>
void BinTree<T>::NodeSize_(node* rootTemp, size_t& size)
{
if (rootTemp == nullptr)
return;
NodeSize_(rootTemp->left, size);
++size;
NodeSize_(rootTemp->right, size);
}
template<typename T>
size_t BinTree<T>::LeafNodesize()
{
return LeafNodeSize_(root);
}
template<typename T>
size_t BinTree<T>::LeafNodeSize_(node * root)
{
// 二叉树为空的时候
if (root == NULL)return 0;
// 二叉树只有一个节点的时候
if (root->left == NULL && root->right == NULL)
return 1;
// 叶子节点 = 左子树叶子节点 + 右子树叶子节点
return LeafNodeSize_(root->left) + LeafNodeSize_(root->right);
}
template<typename T>
inline bool BinTree<T>::isCompleteTree()
{
queue<node*>q;
if (root)
q.push(root);
bool flag = true;
while (!q.empty())
{
node* front = q.front();
q.pop();
if (front->left)
{
if (flag == false)
return false;
q.push(front->left);
}
else
flag = false;
if (front->right)
{
if (flag == false)
return false;
q.push(front->right);
}
else
flag = false;
}
return true;
}
template<typename T>
BinTreeNode<T>* BinTree<T>::Find(const T & x)
{
return Find_(root, x);
}
template<typename T>
size_t BinTree<T>::Height()
{
return Height_(root);
}
template<typename T>
size_t BinTree<T>::Height_(node* root)
{
//二叉树为空的时候,高度为0
if (root == nullptr) return 0;
size_t leftHeight = Height_(root->left);
size_t rightHeight = Height_(root->right);
//二叉树非空时,高度为左子树和右子树中较高的一个
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
template<typename T>
size_t BinTree<T>::NodeSizeKth(size_t k)
{
return NodeSizeKth_(root, k);
}
template<typename T>
size_t BinTree<T>::NodeSizeKth_(node* root,size_t k)
{
//空树返回0
if (root == nullptr) return 0;
//第一层只有一个节点
if (k == 1) return 1;
//注意这里为什么是k-1? 如果你需要求第二层的节点个数,则需要用第一层的根节点访问他的左子树和右子树的第一层的个数
return NodeSizeKth_(root->left, k - 1) + NodeSizeKth_(root->right, k - 1);
}
template<typename T>
BinTreeNode<T>* BinTree<T>::Find_(node* root, const T & x)
{
if (root == nullptr)
return nullptr;
if (root->data == x)
return root;
node* ret1 = Find_(root->left, x);
if (ret1)return ret1;
node* ret2 = Find_(root->data, x);
if (ret2)return ret2;
return nullptr;
}