二叉搜索树模板

二叉树:每个节点最多只有两个节点

二叉搜索树:

性质:左子树不为空,左节点上的值都必须小于根节点上的值,若右子树不为空,右节点上的值必须大于根节点上的值

体现在insert这个步骤上

template <typename T>
void BSTree<T>::insert(T key)
{
	BSNode<T>* pparent = nullptr;
	BSNode<T>* pnode = root;
	while (pnode != nullptr)
	{
		pparent = pnode;
		if (key > pnode->value)
		{
			pnode = pnode->rchild;
		}
		else if (key < pnode->value)
		{
			pnode = pnode->lchild;
		}
		else
		{
			break;
		}
	}
	pnode = new BSNode<T>(key);
	if (pparent == nullptr)
	{
		root = pnode;
	}
	else
	{
		if (key > pparent->value)
		{
			pparent->rchild = pnode;
		}
		else
		{
			pparent->lchild = pnode;
		}
	}
	pnode->parent = pparent;
}

平衡二叉树:

树中每棵子树都满足其左子树和右子树的深度差不超过1

1.前驱和后驱

中序遍历:4 2 5 1 6 3 7

1的前驱节点是5  1的后继节点是6

因此

某点前驱节点的判断:

1.若该节点有左子树,则其前驱节点为左子树最右边

2.若该节点无左子树,且其为右子树中,则前驱节点为其父节点

后继节点判断

1.若该节点有右子树,则其后继节点为右子树最左边

2.若该节点无右子树,且其为左子树中,则后继节点为其父节点

 模板代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>
#include<string>
using namespace std;
#define MAX_SIZE 128
template <typename T>
class BSNode
{
public:
	BSNode(T t):value(t),lchild(nullptr),rchild(nullptr),parent(nullptr){}
	BSNode() :lchild(NULL), rchild(NULL), parent(NULL) {};
	T value;
	BSNode<T>* lchild;
	BSNode<T>* rchild;
	BSNode<T>* parent;
};
template<typename T>
class Queue
{
public:
	Queue<T>() : front(-1), rear(-1) { data[MAX_SIZE] = {}; }
	int front;
	int rear;
	BSNode<T>*data[MAX_SIZE];
};
template<typename T>
void initQueue(Queue<T>* q)
{
	q->front = q->rear = -1;
}
template<typename T>
bool emptyQueue(Queue<T>* q)
{
	if (q->front == q->rear)
	{
		return true;
	}
	return false;
}
template<typename T>
bool enQueue(Queue<T>* q, BSNode<T>* &node)
{
	if (q->rear == MAX_SIZE - 1)//队列已满
	{
		return false;
	}
	q->rear++;//负责加元素
	q->data[q->rear] = node;
	return true;
}
template<typename T>
bool deQueue(Queue<T>* q, BSNode<T>* &node)
{
	if (q->front == q->rear)//队列为空
	{
		return false;
	}
	q->front++;//负责取元素
	node = q->data[q->front];//取值
	return true;
}
template <typename T>
class BSTree
{
public:
	BSTree() { BSNode<T>(); };
	~BSTree() { destory(); };
	void preOrder();
	void inOrder();
	void postOrder();
	void layerOrder();
	BSNode<T>* search_Iterator(T key);//迭代进行查找
	T search_minnum();//查找最小元素
	T search_maxnum();//查找最大元素
	BSNode<T>*successor(BSNode<T>* x);//查找指定节点的后继节点
	BSNode<T>*predecessor(BSNode<T>*x);//查找指定节点的前驱节点
	void insert(T key);
	void remove(T key);//删除指定节点
	void destory();
private:
	BSNode<T>* root;
	//BSNode<T>* search(BSNode<T>*& p, T key);
	void remove(BSNode<T>* p, T key);
	void preOrder(BSNode<T>* p);
	void inOrder(BSNode<T>* p);
	void postOrder(BSNode<T>* p);
	void layerOrder(BSNode<T>* &p);
	T search_minnum(BSNode<T>* p);
	T search_maxnum(BSNode<T>* p);
	void destory(BSNode<T>*& p);

};
template <typename T>
void BSTree<T>::insert(T key)
{
	BSNode<T>* pparent = nullptr;
	BSNode<T>* pnode = root;
	while (pnode != nullptr)
	{
		pparent = pnode;
		if (key > pnode->value)
		{
			pnode = pnode->rchild;
		}
		else if (key < pnode->value)
		{
			pnode = pnode->lchild;
		}
		else
		{
			break;
		}
	}
	pnode = new BSNode<T>(key);
	if (pparent == nullptr)
	{
		root = pnode;
	}
	else
	{
		if (key > pparent->value)
		{
			pparent->rchild = pnode;
		}
		else
		{
			pparent->lchild = pnode;
		}
	}
	pnode->parent = pparent;
}
template <typename T>
void BSTree<T>::preOrder()
{
	preOrder(root);
}
template <typename T>
//根左右
void BSTree<T>::preOrder(BSNode<T>* p)
{
	if (p != nullptr)
	{
		cout << p->value << endl;
		preOrder(p->lchild);
		preOrder(p->rchild);
	}
}
template <typename T>
void BSTree<T>::inOrder()
{
	inOrder(root);
}
template <typename T>
//左根右
void BSTree<T>::inOrder(BSNode<T>* p)
{
	if (p != nullptr)
	{
		inOrder(p->lchild);
		cout << p->value << endl;
		inOrder(p->rchild);
	}
}
template <typename T>
void BSTree<T>::postOrder()
{
	postOrder(root);
}
template <typename T>
//左右根
void BSTree<T>::postOrder(BSNode<T>* p)
{
	if (p != nullptr)
	{
		postOrder(p->lchild);
		postOrder(p->rchild);
		cout << p->value << endl;
	}
}
template <typename T>
void BSTree<T>::layerOrder()
{
	layerOrder(root);
}
template <typename T>
void BSTree<T>::layerOrder(BSNode<T>*& p)//一定要用取址符 才能改变值 指针是用来移动的
{
	Queue<T>* q=new Queue<T>();//定义队列
	initQueue(q);
	if (p != NULL)
	{
		enQueue(q, p);
	}
	while (!emptyQueue(q))
	{
		deQueue(q, p);
		printf("%d ", p->value);
		if (p->lchild != NULL)
		{
			enQueue(q, p->lchild);
		}
		if (p->rchild != NULL)
		{
			enQueue(q, p->rchild);
		}

	}
}
//前驱节点 中序遍历时某个节点的前一个节点
template<typename T>
BSNode<T>* BSTree<T>::predecessor(BSNode<T>* pnode)
{
	if (pnode->lchild != nullptr)//有左子树 则其前驱为左子树树最右边的节点
	{
		pnode = pnode->lchild;
		while (pnode->rchild != nullptr)
		{
			pnode = pnode->rchild;
		}
		return pnode;
	}
	BSNode<T>* pparent = pnode->parent;
	while (pparent != nullptr && pparent->lchild == pnode)//直到该节点为父节点的右节点
	{
		pnode = pparent;
		pparent = pparent->parent;
	}
	return pparent;
}
template<typename T>
BSNode<T>* BSTree<T>::successor(BSNode<T>* pnode)
{
	if (pnode->rchild != nullptr)//有右子树 则其后继为右子树最左边的节点
	{
		pnode = pnode->rchild;
		while (pnode->lchild != nullptr)
		{
			pnode = pnode->lchild;
		}
		return pnode;
	}
	BSNode<T>* pparent = pnode->parent;
	while (pparent != nullptr && pparent->rchild == pnode)//若无右子树且是左孩子,则为其父节点
	{
		pnode = pparent;
		pparent = pparent->parent;
	}
	return pparent;
}
template <typename T>
void BSTree<T>::remove(T key)
{
	remove(root,key);
}
template <typename T>
void BSTree<T>::remove(BSNode<T>* pnode,T key)
{
	if (pnode != nullptr)
	{
		if (pnode->value == key)
		{
			BSNode<T>* pdel = nullptr;
			if (pnode->lchild == nullptr || pnode->rchild == nullptr)
			{
				pdel = pnode;
			}
			else
			{
				pdel = predecessor(pnode);
			}
			BSNode<T>* pchild = nullptr;
			//删除结点只有一个孩子或者没有孩子 保存该孩子的指针
			if (pdel->lchild != nullptr)
			{
				pchild = pdel->lchild;
			}
			else
			{
				pchild = pdel->rchild;
			}
			//让孩子指向被删除节点的父节点
			if (pchild != nullptr)
			{
				pchild->parent = pdel->parent;
			}
			//如果要删除的结点是头结点
			if (pdel->parent == nullptr)
			{
				root = pchild;
			}
			//如果双亲节点不是头节点,要注意更改它的双亲节点指向新的孩子节点
			else if (pdel->parent->lchild == pdel)
			{
				pdel->parent->lchild = pchild;
			}
			else
			{
				pdel->parent->rchild = pchild;
			}
			if (pnode->value != pdel->value)
			{
				pnode->value = pdel->value;
			}
			delete pdel;
		}
		//递归进行删除
		else if (key > pnode->value)
		{
			remove(pnode->rchild, key);
		}
		else
		{
			remove(pnode->lchild, key);
		}
	}
}
template<typename T>
BSNode<T>* BSTree<T>::search_Iterator(T key)
{
	BSNode<T>* pnode = root;
	while (pnode != nullptr)
	{
		if (key == pnode->value) { return pnode; }
		if (key > pnode->value) { pnode = pnode->rchild; }
		else { pnode = pnode->lchild; }
	}
	return nullptr;
}
template <typename T>
T BSTree<T>::search_minnum()
{
	return search_minnum(root);
}
template <typename T>
T BSTree<T>::search_minnum(BSNode<T>* p)
{
	if (p->lchild != nullptr)
	{
		return search_minnum(p->lchild);
	}
	return p->value;
}
template <typename T>
T BSTree<T>::search_maxnum()
{
	return search_maxnum(root);
}
template <typename T>
T BSTree<T>::search_maxnum(BSNode<T>* p)
{
	if (p->rchild != nullptr)
	{
		return search_maxnum(p->rchild);
	}
	return p->value;
}
template <typename T>
void BSTree<T>::destory()
{
	destory(root);
}
template <typename T>
void BSTree<T>::destory(BSNode<T>* &p)
{
	if (p != nullptr)
	{
		if (p->lchild != nullptr)
		{
			destory(p->lchild);
		}
		if (p->rchild != nullptr)
		{
			destory(p->rchild);
		}
		delete p;
		p = nullptr;
	}
}
int main()
{
	BSTree<int> t;
	t.insert(62);
	t.insert(58);
	t.insert(47);
	t.insert(51);
	t.insert(35);
	t.insert(37);
	t.insert(88);
	t.insert(73);
	t.insert(99);
	t.insert(93);
	t.insert(95);
	cout << endl << "中序遍历:" << endl;
	t.inOrder();
	cout << endl << "层次遍历: " << endl;
	t.layerOrder();
	cout << endl;
	cout << "最大元素:" << t.search_maxnum() << endl;
	cout << "最小元素:" << t.search_minnum() << endl;
	cout << "删除元素99" << endl;
	t.remove(99);
	cout << "最大元素:" << t.search_maxnum() << endl;
	t.destory();
	getchar();
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值