BST,AVL的c++实现

本文介绍使用C++实现二叉搜索树(BST)和平衡二叉树(AVL)的方法,包括插入、删除、查找等核心操作,并提供详细的代码实现及验证。通过实例演示了如何使用这些数据结构进行数据的高效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

运行结果显示的是后序排列
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值