1.BST二叉搜索树的c++实现及验证
/************************************************************************
> File Name: BST.cpp
> Author: wpf
> Mail: wpf9264@163.com
> Created Time: 2019年03月01日 星期五 16时12分17秒
************************************************************************/
#include<iostream>
using namespace std;
template<typename Comparable>
class BST
{
private:
//树节点
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const Comparable & x,BinaryNode *lt,BinaryNode *rt):element{x},left{lt},right{rt}
{}
BinaryNode(Comparable && x,BinaryNode *lt,BinaryNode *rt):element{std::move(x)},left{lt},right{rt}
{}
};
BinaryNode *root;
public:
BST()
{
root = NULL;
}
BST(const Comparable & x)
{
root = new BinaryNode{x,NULL,NULL};
}
//拷贝构造
BST(const BST & rhs):root{NULL}
{
root = clone(rhs.root);
}
//移动构造
BST(BST && rhs):root{std::move(rhs.root)}
{ }
//析构
~BST()
{
makeEmpty();
}
BST & operator=(const BST & rhs)
{
if(this != &rhs)
{
BST tmp{rhs};
std::swap(*this,tmp);
}
return *this;
}
BST & operator=(BST && rhs)
{
std::swap(root,rhs.root);
}
const Comparable & findMin()const
{
return findMin(root)->element;
}
const Comparable & findMax()const
{
return findMax(root)->element;
}
bool contains(const Comparable & x)const
{
return contains(x,root);
}
bool isEmpty()const
{
return root == NULL;
}
void printTree(ostream & out = std::cout)const
{
printTree(root,out);
out<<endl;
}
void makeEmpty()
{
makeEmpty(root);
}
void insert(const Comparable & x)
{
insert(x,root);
}
void insert(Comparable && x)
{
insert(x,root);
}
void remove(const Comparable & x)
{
remove(x,root);
}
private:
//插入函数的左值版本
void insert(const Comparable & x,BinaryNode* & t)
{
if(t == NULL)
t = new BinaryNode{x,NULL,NULL};
else if(x < t->element)
insert(x,t->left);
else if(x > t->element)
insert(x,t->right);
else
;
}
//插入函数的右值版本
void insert(Comparable && x,BinaryNode* & t)
{
if(t == NULL)
t = new BinaryNode*{std::move(x),NULL,NULL};
else if(x < t->element)
insert(std::move(x),t->left);
else if(x > t->element)
insert(std::move(x),t->right);
else
;
}
//删除函数
void remove(const Comparable & x,BinaryNode * & t)
{
if(t == NULL)
return;
if(x < t->element)
remove(x,t->left);
else if(x > t->element)
remove(x,t->right);
else if(t->left !=NULL && t->right != NULL) //找到了x,并且它有两个孩子
{
t->element = findMax(t->right)->element;
remove(t->element,t->right);
}
else //x只有一个孩子,或者没有孩子
{
BinaryNode* oldNode = t;
t = (t->left != NULL)?t->left:t->right;
delete oldNode;
}
}
//最小值
BinaryNode* findMin(BinaryNode* t)const
{
if(t != NULL)
while(t->left != NULL)
t = t->left;
return t;
}
//最大值
BinaryNode* findMax(BinaryNode* t)const
{
if( t == NULL)
return NULL;
if(t->right == NULL)
return t;
return findMax(t->right);
}
//查询函数
bool contains(const Comparable & x,BinaryNode* t)const
{
if(t == NULL)
return false;
else if(x > t->element)
contains(x,t->right);
else if(x < t->element)
contains(x,t->left);
else
return true;
}
//清空
void makeEmpty(BinaryNode* & t)
{
if(t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t= NULL;
}
//打印函数
void printTree(BinaryNode* t,ostream & out)const
{
if(t == NULL)
return;
//前序,中序,后序仅仅变动打印的顺序即可,很简单
printTree(t->left,out);
printTree(t->right,out);
cout<<t->element<<" ";
}
//复制函数,用于拷贝构造
BinaryNode* clone(BinaryNode* t)const
{
if(t == NULL)
return NULL;
else
return new BinaryNode{t->element,clone(t->left),clone(t->right)};
}
};
int main(int argc,char** argv)
{
BST<int> b{8};
b.insert(2);
b.insert(0);
b.insert(6);
b.insert(9);
b.insert(7);
b.insert(4);
cout<<"************ 以下为测试成员函数功能**************"<<endl;
cout<<"printTree(): ";
b.printTree();
cout<<"remove(7) : ";
b.remove(7);
b.printTree();
cout<<"isEmpty(): "<<b.isEmpty()<<endl;
cout<<"findMin(): "<<b.findMin()<<endl;
cout<<"findMax(): "<<b.findMax()<<endl;
cout<<"contains(10): "<<b.contains(10)<<endl;
cout<<"contains(0): "<<b.contains(0)<<endl;
cout<<"************ 以下为测试构造函数 ***************"<<endl;
BST<int> n;
cout<<n.isEmpty()<<endl;
n = b;
n.printTree();
return 0;
}
以下为测试结果:
2.平衡二叉树的c++实现及验证
/************************************************************************
> File Name: AVL.cpp
> Author: wpf
> Mail: wpf9264@163.com
> Created Time: 2019年03月02日 星期六 18时11分17秒
************************************************************************/
#include<iostream>
using namespace std;
template<typename Comparable>
class AVL
{
private:
//树节点
struct AvlNode
{
Comparable element;
AvlNode *left;
AvlNode *right;
int height;
AvlNode(const Comparable & x,AvlNode *lt,AvlNode *rt,int h=0):element{x},left{lt},right{rt},height(h)
{}
AvlNode(Comparable && x,AvlNode *lt,AvlNode *rt,int h=0):element{std::move(x)},left{lt},right{rt},height{h}
{}
};
AvlNode *root;
public:
AVL()
{
root = NULL;
}
AVL(const Comparable & x)
{
root = new AvlNode{x,NULL,NULL};
}
//拷贝构造
AVL(const AVL & rhs):root{NULL}
{
root = clone(rhs.root);
}
//移动构造
AVL(AVL && rhs):root{std::move(rhs.root)}
{ }
//析构
~AVL()
{
makeEmpty();
}
//深拷贝
AVL & operator=(const AVL & rhs)
{
if(this != &rhs)
{
AVL tmp{rhs};
std::swap(*this,tmp);
}
return *this;
}
//移动复制运算符
AVL & operator=(AVL && rhs)
{
std::swap(root,rhs.root);
return *this;
}
const Comparable & findMin()const
{
return findMin(root)->element;
}
const Comparable & findMax()const
{
return findMax(root)->element;
}
bool contains(const Comparable & x)const
{
return contains(x,root);
}
bool isEmpty()const
{
return root == NULL;
}
void printTree(ostream & out = std::cout)const
{
if(isEmpty())
out<<"empty tree";
else
printTree(root,out);
out<<endl;
}
void makeEmpty()
{
makeEmpty(root);
}
void insert(const Comparable & x)
{
insert(x,root);
}
void insert(Comparable && x)
{
insert(std::move(x),root);
}
void remove(const Comparable & x)
{
remove(x,root);
}
private:
//插入函数的右值版本
void insert(const Comparable & x,AvlNode* & t)
{
if(t == NULL)
t = new AvlNode{x,NULL,NULL};
else if(x < t->element)
insert(x,t->left);
else if(x > t->element)
insert(x,t->right);
else
;
balance( t );
}
//插入函数的左值版本
void insert(Comparable && x,AvlNode* & t)
{
if(t == NULL)
t = new AvlNode{std::move(x),NULL,NULL,0};
else if(x < t->element)
insert(std::move(x),t->left);
else if(x > t->element)
insert(std::move(x),t->right);
else
;
balance( t );
}
//删除函数
void remove(const Comparable & x,AvlNode * & t)
{
if(t == NULL)
return;
if(x < t->element)
remove(x,t->left);
else if(x > t->element)
remove(x,t->right);
else if(t->left !=NULL && t->right != NULL) //找到了x,并且它有两个孩子
{
t->element = findMax(t->right)->element;
remove(t->element,t->right);
}
else //x只有一个孩子,或者没有孩子
{
AvlNode *oldNode = t; //记得要释放要删除节点的内存
t = (t->left != NULL)?t->left:t->right;
delete oldNode;
}
balance( t );
}
//最小值
AvlNode* findMin(AvlNode* t)const
{
if(t != NULL)
while(t->left != NULL)
t = t->left;
return t;
}
//最大值
AvlNode* findMax(AvlNode* t)const
{
if( t == NULL)
return NULL;
if(t->right == NULL)
return t;
return findMax(t->right);
}
//查询函数,递归版本
bool contains(const Comparable & x,AvlNode* t)const
{
if(t == NULL)
return false;
else if(x > t->element)
contains(x,t->right);
else if(x < t->element)
contains(x,t->left);
else
return true;
}
/******非递归版本********************
bool contains( const Comparable & x, AvlNode *t ) const
{
while( t != nullptr )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return true; // Match
return false; // No match
}
*****************************************************/
//清空
void makeEmpty(AvlNode* & t)
{
if(t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t= NULL;
}
//打印函数
void printTree(AvlNode* t,ostream & out)const
{
if(t == NULL)
return;
//前序,中序,后序仅仅变动打印的顺序即可,很简单
printTree(t->left,out);
printTree(t->right,out);
cout<<t->element<<" ";
}
//复制函数,用于拷贝构造
AvlNode* clone(AvlNode* t)const
{
if(t == NULL)
return NULL;
else
return new AvlNode{t->element,clone(t->left),clone(t->right),t->height};
}
int height(AvlNode * t)const
{
return t==NULL?-1:t->height;
}
int max(int lhs,int rhs)const
{
return lhs>rhs?lhs:rhs;
}
/**右旋转,对应情形1,以k2为轴,转动k2的左孩子k1 */
void rotateWithLeftChild( AvlNode * & k2 )
{
AvlNode *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max( height( k2->left ), height( k2->right ) ) + 1;
k1->height = max( height( k1->left ), k2->height ) + 1;
k2 = k1;
}
/**左旋转,对应情形4,以k2为轴,转动k2的右孩子k1 */
void rotateWithRightChild( AvlNode * & k2 )
{
AvlNode *k1 = k2->right;
k2->right = k1->left;
k1->left = k2;
k2->height = max( height( k2->left ), height( k2->right ) ) + 1;
k1->height = max( height( k1->right ), k2->height ) + 1;
k2 = k1;
}
/**左-右旋转对应情形2,先旋转k3的左孩子k2的右孩子k1,再旋转k3新的左孩子 */
void doubleWithLeftChild( AvlNode * & k3 )
{
rotateWithRightChild( k3->left );
rotateWithLeftChild( k3 );
}
/*右-左旋转对应情形3,选旋转k3的右孩子k2的左孩子k1,再旋转k3新的右孩子 */
void doubleWithRightChild( AvlNode * & k1 )
{
rotateWithLeftChild( k1->right );
rotateWithRightChild( k1 );
}
static const int ALLOWED_IMBALANCE = 1;
// 平衡函数
void balance( AvlNode * & t )
{
if( t == nullptr )
return;
if( height( t->left ) - height( t->right ) > ALLOWED_IMBALANCE )
if( height( t->left->left ) >= height( t->left->right ) )
rotateWithLeftChild( t ); //情形1
else
doubleWithLeftChild( t ); //情形2
else
if( height( t->right ) - height( t->left ) > ALLOWED_IMBALANCE )
if( height( t->right->right ) >= height( t->right->left ) )
rotateWithRightChild( t ); //情形4
else
doubleWithRightChild( t ); //情形3
t->height = max( height( t->left ), height( t->right ) ) + 1;
}
};
int main(int argc,char** argv)
{
AVL<int> b{8};
b.insert(2);
b.insert(0);
b.insert(6);
b.insert(9);
b.insert(7);
b.insert(4);
cout<<"printTree(): ";
b.printTree();
return 0;
}
运行结果显示的是后序排列