二叉查找树(搜索树)BST各类操作(c++完整实现)


    网上一堆,简单总结小小练习下大笑

/**************节点结构*****************/
template<class T>
class BinaryNode
{
public:
	BinaryNode();
	BinaryNode(const T &value, BinaryNode<T>* l = NULL, BinaryNode<T>* r = NULL);
	~BinaryNode();
private:
	T element;
	BinaryNode<T> *left;
	BinaryNode<T> *right;
};
//构造析构
template<class T>
BinaryNode<T>::BinaryNode()
{
	left = NULL;
	right = NULL;
};
template<class T>
BinaryNode<T>::BinaryNode(const T &value, BinaryNode<T>* l = NULL, BinaryNode<T>* r = NULL)
{
	element = value;
	left = l;
	right = r;
};

/*************构建树*************/
template<class T>
class BinaryTree
{
public:

	BinaryTree();
	~BinaryTree();
	void DestroyTree(BinaryNode<T>* &n);

	void FindNode(BinaryNode<T>* &n, T x);
	void InsertNode(T x);
	void InsertNodeRecursive(BinaryNode<T>* &n, T x);
	void DleteNode(BinaryNode<T>* &n,T x);

	void Pre_Order(BinaryNode<T> *n) const;
	void In_Order(BinaryNode<T> *n) const;
	void Post_Order(BinaryNode<T> *n) const;

	int CountHight(BinaryNode<T>* n) const;
	int CountNode(BinaryNode<T>* n) const;
	int CountNodeof1(BinaryNode<T>* n) const;
	int Countleaf(BinaryNode<T>* n) const;

private:
	BinaryNode<T>* root;
};
//构造析构
template<class T>
BinaryTree<T>::BinaryTree()
{
	root = new BinaryNode<T>;
	if (root = NULL)    //assert(root!=null);
	{
		throw new std::exception("alloc error");
	}
};
template<class T>
BinaryTree<T>::~BinaryTree()
{
	DestroyTree(root);
};

template<class T>
void BinaryTree<T>::DestroyTree(BinaryNode<T>* &node)   
{
	if (node != NULL)
	{
		DestroyTree(node->left);
		DestroyTree(node->right);
		delete node;   
		node = NULL;
	}
};

    //查找
template<class T>
void BinaryTree<T>::FindNode(BinaryNode<T>* &n, T x)
{
	if (NULL == n)
	{
		cout << "not found";
	}
	if (n->element > x)
		FindNode(n->left, x);
	if (n->element < x)
		FindNode(n->right, x);
	else
		cout << "found";
};

    //插入节点:非递归
template<class T>
void BinaryTree<T>::InsertNode(T x)
{
	BinaryNode<T>* newnode = new BinaryNode<T>;
	assert( newnode!= null);
	newnode->element = x;
	newnode->right = newnode->left = NULL;

	//节点为根
	if (root == NULL)
		root = newnode;
	else
	{
		BinaryNode<T> *back;   
		BinaryNode<T> *current = root; 
		while (current != NULL)
		{
			back = current;
			if (current->element>x)
				current = current->left;
			else
				current = current->right;
		}
		if (back->data>x)
			back->left = newnode;
		else
			back->right = newnode;
	}
};
    //插入节点,递归
template<class T>
void BinaryTree<T>::InsertNodeRecursive(BinaryNode<T>* &n, T x)
{
	if (NULL == n)
	{
		BinaryNode<T> *newnode = new BinaryNode < T >(x);
		assert(null != newnode);
		n = newnode;
		return;
	}
	if (n->element>x)
		Insert(n->left, x);
	else
		Insert(n->right, x);
};
    //删除节点
template<class T>
void BinaryTree<T>::DleteNode(BinaryNode<T>* &n, T x)
{
	if (NULL == n) return;

	BinaryNode<T>* prt = NULL;  //待删除点的父节点
	BinaryNode<T>* crt = n;

	    //找到相应位置
	while ((NULL != crt) && (crt->element != x))
	{
		prt = crt;
		if (crt->element > x)
			crt = crt->left;
		else
			crt = crt->right;
	}
	//没找到
	if (NULL == crt) return;


	     //1、无子节点
	if ((NULL == crt->left) && (NULL == crt->right))
	{
		//1.1、为根节点
		if (crt == n)
		{
			n = NULL;    
		}
		//1.2、为叶子节点
		else
		{
			if (prt->left == crt)
				prt->left = NULL;    //对父左
			else
				prt->right = NULL;    //对父右
		}
	}

	  //2、有左子树,没有右子树
	if ((NULL != crt->left) && (NULL == crt->right))
	{
		//为根
		if (crt == n)
		{
			n = n->left;
		}
		else
		{
			if (crt == prt->left)
				prt->left = crt->left;//连父左
			else
				prt->right = crt->left;//连父右
		}

	}

	    //2、有右子树,没有左子树
	if ((NULL == crt->left) && (NULL != crt->right))
	{
		//根
		if (crt == n)
		{
			n = n->right;
		}
		else
		{
			if (crt == prt->left)
				prt->left = crt->right;//连父左
			else
				prt->right = crt->right;//连父右
		}
	}

	    //3、左右子树都存在,则将右子树最左端节点复制到待删除节点
	if ((NULL != crt->_lchild) && (NULL != crt->_rchild))
	{
		// 得到右子的最小的父
		//右子树无左、一左/二左(移1步)
		BinaryNode<T>* pre = crt->right;

		while ((NULL != pre->left) && (NULL != pre->left->left))
			pre = pre->left;

		BinaryNode<T>* p = NULL;  //临时
		//1、右子树一左  / 二左(移1步后)
		if (NULL != pre->left)
		{
			//移一步,取出最小左(父左子设为NULL)
			p = pre->left;
			pre->left = NULL;

			//连右最小的子
			p->left = crt->_lchild;
			p->right = crt->_rchild;

		}
		//2、右子树无左
		else
		{
			p = pre;
			p->left = crt->left;
		}

		//3、删除点为根,则不用下面的父连接
		if (crt == n)
		{
			delete n;
			n = p;  //NULL
			return;
		}

	    	//连接
		if (crt == prt->left)
			prt->left = p; //连父左
		else
			prt->right = p;//连父右
	}

	delete crt;
	//crt=NULL;

}
//3中遍历
template<class T>
void BinaryTree<T>::Pre_Order(BinaryNode<T> *n) const
{
	if (n != NULL)
	{
		cout << n->element << " ";
		Pre_Order(n->left);
		Pre_Order(n->right);
	}
};

template<class T>
void BinaryTree<T>::In_Order(BinaryNode<T> *n) const
{
	if (n != NULL)
	{
		In_Order(n->left);
		cout << n->data << " ";
		In_Order(n->right);
	}
};

template<class T>
void BinaryTree<T>::Post_Order(BinaryNode<T> *n) const
{
	if (n != NULL)
	{
		Post_Order(n->left);
		Post_Order(n->right);
		cout << n->data << " ";
	}
};

    //二叉树节点个数
template<class T>
int BinaryTree<T>::CountNode(BinaryNode<T>* n) const
{
	if (n == NULL)
		return 0;
	else
		return CountNode(n->left) + CountNode(n->right) + 1;
};

    //二叉树叶子个数
template<class T>
int BinaryTree<T>::Countleaf(BinaryNode<T> *n) const    //**
{
	if (n == NULL)
		return 0;
	else
	{
		if (n->left == NULL&&n->right == NULL)
			return 1;
		else
		{
			int lc, rc;
			lc=Countleaf(n->left);
			rc=Countleaf(n->right);
			return lc + rc;
		}
	}
};

//二叉树中度数为1的结点的数量为
template<class T>
int BinaryTree<T>::CountNodeof1(BinaryNode<T>* n) const
{
	if (n == NULL)
		return 0;
	else
	{
		int lc, rc;
		if (n->left != NULL&&n->right != NULL)
		{
			lc = CountNodeof1(n->left);
			rc = CountNodeof1(n->right);
			return  lc+rc;
		}
		if (n->left != NULL&&n->right == NULL)
		{
			lc=CountNodeof1(n->left);
			return lc + 1;
		}
		if (n->left == NULL&&temp->right != NULL)
		{
			rc=CountNodeof1(n->right);
			return rc + 1;
		}
		else
		{
			return 0;
		}
	}
};

//二叉树的高度
template<class T>
int BinaryTree<T>::CountHight(BinaryNode<T>* n) const
{
	if (n == NULL)
		return 0;
	else
	{
		int lh, rh;
		lh = CountHight(n->left);
		rh = CountHight(n->right);
		return 1 + (lh>rh ? lh : rh);
	}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值