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


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

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

/*************构建树*************/
template
class BinaryTree
{
public:

	BinaryTree();
	~BinaryTree();
	void DestroyTree(BinaryNode* &n);

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

	void Pre_Order(BinaryNode *n) const;
	void In_Order(BinaryNode *n) const;
	void Post_Order(BinaryNode *n) const;

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

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

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

    //查找
template
void BinaryTree::FindNode(BinaryNode* &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
void BinaryTree::InsertNode(T x)
{
	BinaryNode* newnode = new BinaryNode;
	assert( newnode!= null);
	newnode->element = x;
	newnode->right = newnode->left = NULL;

	//节点为根
	if (root == NULL)
		root = newnode;
	else
	{
		BinaryNode *back;   
		BinaryNode *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
void BinaryTree::InsertNodeRecursive(BinaryNode* &n, T x)
{
	if (NULL == n)
	{
		BinaryNode *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
void BinaryTree::DleteNode(BinaryNode* &n, T x)
{
	if (NULL == n) return;

	BinaryNode* prt = NULL;  //待删除点的父节点
	BinaryNode* 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* pre = crt->right;

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

		BinaryNode* 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
void BinaryTree::Pre_Order(BinaryNode *n) const
{
	if (n != NULL)
	{
		cout << n->element << " ";
		Pre_Order(n->left);
		Pre_Order(n->right);
	}
};

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

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

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

    //二叉树叶子个数
template
int BinaryTree::Countleaf(BinaryNode *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
int BinaryTree::CountNodeof1(BinaryNode* 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
int BinaryTree::CountHight(BinaryNode* 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);
	}
};


你可能感兴趣的:(Algrithom)