版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NichChen/article/details/84193412
文中包括BST的:初始化、析构、插入、删除(重点部分)、清空、查找、先序遍历、中序遍历、后序遍历
代码:
bst.h
#ifndef BST_H
#define BST_H
#include <iostream>
template<typename T = int>
class BinaryTree
{
public:
BinaryTree() = default;
BinaryTree(const BinaryTree &bt);
BinaryTree(const T &theElement);
~BinaryTree();
void insert(const T &theElement);
void remove(const T &theElement);
void makeEmpty();
bool isFind(const T &theElement) const;
void preOrder() const;
void inOrder() const;
void postOrder() const;
private:
struct BinaryNode
{
T element;
BinaryNode* leftNode;
BinaryNode* rightNode;
BinaryNode(const T &ele, BinaryNode* left, BinaryNode* right)
: element(ele), leftNode(left), rightNode(right) {}
BinaryNode(const T &ele): element(ele), leftNode(nullptr), rightNode(nullptr){}
BinaryNode(const BinaryNode* bNode)
: element(bNode->element), leftNode(bNode->leftNode), rightNode(bNode->rightNode){}
};
BinaryNode* root;
BinaryNode* clone(const BinaryNode* bNode);
void insert(const T& theElement, BinaryNode* &t);
void remove(const T& theElement, BinaryNode* &t);
void makeEmpty(BinaryNode* &t);
bool isFind(const T &theElement, BinaryNode* t) const;
BinaryNode* findMin(BinaryNode* bNode) const;
BinaryNode* findMax(BinaryNode* bNode) const;
void preOrder(BinaryNode* bNode) const;
void inOrder(BinaryNode* bNode) const;
void postOrder(BinaryNode* bNode) const;
};
#endif // BST_H
bst.cpp
#include <iostream>
#include "bst.h"
template<typename T>
BinaryTree<T>::BinaryTree(const BinaryTree &bt)
{
if(nullptr != bt.root) {
this->root = clone(bt.root);
} else {
root = nullptr;
}
}
template<typename T>
BinaryTree<T>::BinaryTree(const T &theElement)
{
root = new BinaryNode(theElement);
/*
root->element = theElement;
root->leftNode = nullptr;
root->rightNode = nullptr;
*/
}
template<typename T>
BinaryTree<T>::~BinaryTree()
{
makeEmpty();
// root->~BinaryNode();
}
template<typename T>
void BinaryTree<T>::insert(const T &theElement)
{
insert(theElement, root);
}
template<typename T>
void BinaryTree<T>::remove(const T &theElement)
{
remove(theElement, root);
}
template<typename T>
void BinaryTree<T>::makeEmpty()
{
makeEmpty(root);
}
template<typename T>
bool BinaryTree<T>::isFind(const T &theElement) const
{
isFind(theElement, root);
}
template<typename T>
void BinaryTree<T>::preOrder() const
{
preOrder(root);
}
template<typename T>
void BinaryTree<T>::inOrder() const
{
inOrder(root);
}
template<typename T>
void BinaryTree<T>::postOrder() const
{
postOrder(root);
}
template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::clone(const BinaryNode* r)
{
//这个时候typename的作用就是告诉c++编译器,typename后面的字符串为一个类型名称,而不是成员函数或者成员变量
if (nullptr == r)
{
return nullptr;
}
else
{
return new BinaryNode(r->element, clone(r->leftNode), clone(r->rightNode));
}
}
template<typename T>
void BinaryTree<T>::insert(const T &theElement, BinaryNode* &t)
//指针加索引作为形参,保证运行完函数后保存对指针变量的改变操作
{
if (nullptr == t)
{
t = new BinaryNode(theElement);
}
else if (theElement < t->element)
{
insert(theElement, t->leftNode);
}
else if (theElement > t->element)
{
insert(theElement, t->rightNode);
}
else
{
//重复的数据不添加到树中
}
}
/******重点******/
template<typename T>
void BinaryTree<T>::remove(const T &theElement, BinaryNode* &t)
{
if (nullptr == t)
{
return;
}
else
{
if (theElement < t->element)
{
remove(theElement, t->leftNode);
}
else if (theElement > t->element)
{
remove(theElement, t->rightNode);
}
else if (nullptr != t->leftNode && nullptr != t->rightNode) //需要删除的结点有2个孩子结点
{
t->element = findMin(t->rightNode)->element; //找到右子树中的最小值,并赋值给当前待删除结点
remove(t->element, t->rightNode); //删除右子树中的最小点(此时待删除结点一定无左子树)
}
else //需要删除的结点有1或0个孩子结点
{
BinaryNode* oldNode = t;
//这里改变t,就能让t的父结点重新指向t改变后的结点处吗?(引用的作用?)
t = (nullptr != t->leftNode) ? t->leftNode : t->rightNode;
delete oldNode;
}
}
}
template<typename T>
void BinaryTree<T>::makeEmpty(BinaryNode* &t)
{
if (nullptr != t)
{
makeEmpty(t->leftNode);
makeEmpty(t->rightNode);
std::cout << "delete: " << t->element << std::endl;
delete t;
t = nullptr;
}
// t = nullptr
}
template<typename T>
bool BinaryTree<T>::isFind(const T &theElement, BinaryNode *t) const
{
if (nullptr == t)
{
return false;
}
else if (theElement < t->element)
{
return isFind(theElement, t->leftNode);
}
else if (theElement > t->element)
{
return isFind(theElement, t->rightNode);
}
else
{
//匹配
return true;
}
}
template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::findMin(BinaryNode* bNode) const
{
if (nullptr != bNode)
{
while (nullptr != bNode->leftNode)
{
bNode = bNode->leftNode;
}
return bNode;
}
}
template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::findMax(BinaryNode* bNode) const
{
if (nullptr != bNode)
{
while (nullptr != bNode->rightNode)
{
bNode = bNode->rightNode;
}
return bNode;
}
}
template<typename T>
void BinaryTree<T>::preOrder(BinaryNode* bNode) const
{
if (nullptr != bNode)
{
std::cout << bNode->element << " ";
preOrder(bNode->leftNode);
preOrder(bNode->rightNode);
}
}
template<typename T>
void BinaryTree<T>::inOrder(BinaryNode* bNode) const
{
if (nullptr != bNode)
{
inOrder(bNode->leftNode);
std::cout << bNode->element << " ";
inOrder(bNode->rightNode);
}
}
template<typename T>
void BinaryTree<T>::postOrder(BinaryNode* bNode) const
{
if (nullptr != bNode)
{
postOrder(bNode->leftNode);
postOrder(bNode->rightNode);
std::cout << bNode->element << " ";
}
}
main.cpp
#include <iostream>
#include "bst.h"
#include "bst.cpp"
using namespace std;
int main()
{
int root = 5;
int a = 3, b = 4, c = 2, d = 1, e = 8, f = 6;
BinaryTree<int> bTree(root);
bTree.insert(a);
bTree.insert(b);
bTree.insert(c);
bTree.insert(d);
bTree.insert(e);
bTree.insert(f);
cout << "bTree.isFind(7) = " << bTree.isFind(7) << endl;
cout << "bTree.isFind(8) = " << bTree.isFind(8) << endl;
// bTree.
cout << "preOrder:" << endl;
bTree.preOrder();
cout << endl;
cout << "inOrder:" << endl;
bTree.inOrder();
cout << endl;
cout << "postOrder:" << endl;
bTree.postOrder();
cout << endl;
bTree.remove(3);
cout << "after bTree.remove(3), inOrder:" << endl;
bTree.inOrder();
cout << endl;
//bTree.makeEmpty()包含在析构函数中,以后序遍历的方式删除结点
return 0;
}
程序运行结果如下: