数据结构与算法(c++)-二叉树1


概念

在这里插入图片描述

1.这里,树是一种结构,一对多的数据结构,树结构具备递归特性。
2.孩子节点:当前节点的下一层。
3.父节点:指向当前节点的节点。
4.根:树的第一个节点。
5.叶子:末梢,没有孩子的节点。
6.枝干:除了根和叶子,其它节点都是枝干。
7.高度:当前层节点数,比如上图中的3节点,高度为1。

有二叉树,也有一叉树,三叉树,4叉树。它们的区别在于容许最多的孩子数,一叉树就是链表那种结构。

二叉搜索树(有序二叉树)

二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势。
明白两个概念:
升序:左节点的数据 < 父节点的数据 < 有节点的数据(一般使用这种)
降序:左节点的数据 > 父节点的数据 > 有节点的数据

一般不存相同的数据,如果有,放左边也行,右边也行。

template<class T>
class Tree
{
public:
	class Node
	{
	public:
		T data;
		Node* pLeft;
		Node* pRight;
		Node(T insert_data) { data = insert_data; pLeft = NULL; pRight = NULL; }

	};
	Node* Atree;
	Tree(T root_data);
	void insert(T insert_data);
	void Del(T delete_data);
private:
//这些函数一般不向外界展示
	bool _insert(T data, Node*& root);
	void _Del(T data, Node*& root);
	void main_del(Node*& pDelNode);
};
//构造函数
template<class T>
Tree<T>::Tree(T root_data)
{
	Atree = new Node(root_data);
}
//插入函数
template<class T>
void Tree<T>::insert(T insert_data)
{
	_insert(insert_data, Atree);				//调用递归函数
}
//删除函数
template<class T>
void Tree<T>::Del(T data)
{
	_Del(data, Atree);
}

用于插入数据的递归函数
保证每次插入完后,树结构依然有序。

template<class T>
bool Tree<T>::_insert(T data, Node*& root)
{
	if (!root)
	{
		root = new Node(data);
		return true;
	}

	if (root->data >= data)
	{
		_insert(data, root->pLeft);
	}
	else
	{
		_insert(data, root->pRight);
	}

	return false;
}

从根节点按照大小比较的方式递归寻找合适的位置,然后插入。

用于删除的递归函数

template<class T>
bool Tree<T>::_Del(T data, Node*& root)
{
	if (!root)
	{
		return false;
	}
	if (data == root->data)
	{
		main_del(root);			//调用删除函数
		return true;
	}
	else if (data < root->data)
	{
		_Del(data, root->pLeft);
	}
	else
	{
		_Del(data, root->pRight);
	}
	return false;
}

删除的主要函数
要保证删除后依然有序,所以需要做调整,考虑到所有情况。

template<class T>
void Tree<T>::main_del(Node*& pDelNode)
{
	//节点是根节点
	if (pDelNode == Atree)
	{
		//没有右孩子,则让左孩子成为新的根节点
		if (NULL == pDelNode->pRight)
		{
			Node* temp = pDelNode->pLeft;
			delete pDelNode;
			Atree = temp;
			return;
		}
		//有则,先让左孩子成为右孩子的最左孩子,再让右孩子成为新的根节点
		else
		{
			Node* find_temp = pDelNode->pRight;
			while (find_temp->pLeft)find_temp = find_temp->pLeft;
			find_temp->pLeft = pDelNode->pLeft;
			Node* temp = pDelNode->pRight;
			delete pDelNode;
			Atree = temp;		
			return;
		}
		
	}
	//节点不是根节点
	else
	{
		//需要先得到父节点用于连接
		Node* pDelParent = Atree;
		while (pDelParent)
		{
			if ((pDelParent->pLeft != NULL && pDelParent->pLeft->data == pDelNode->data) 
				|| (pDelParent->pRight != NULL && pDelParent->pRight->data == pDelNode->data))break;
			else if (pDelParent->data < pDelNode->data)
			{
				pDelParent = pDelParent->pRight;
			}
			else
			{
				pDelParent = pDelParent->pLeft;
			}
		}
		//没有右孩子,则让左孩子成为新的根节点
		if (NULL == pDelNode->pRight)
		{
			Node* temp = pDelNode->pLeft;
			delete pDelNode;
			//连接,pDelNode是pDelParentNode的右孩子则temp成为pDelParent的右孩子,反之则成为左孩子
			if (pDelParent->pLeft == pDelNode)
				pDelParent->pLeft = temp;
			else
				pDelParent->pRight = temp;
			return;
		}
		//有右孩子
		else
		{
			//先让pDelNode的左孩子成为pDelNode的右孩子的最左孩子
			Node* find_temp = pDelNode->pRight;
			while (find_temp->pLeft)find_temp = find_temp->pLeft;
			find_temp->pLeft = pDelNode->pLeft;
			//接着pDelNode的右孩子继承pDelNode的位置
			Node* temp = pDelNode->pRight;
			delete pDelNode;
			//pDelNode是pDelParentNode的右孩子则temp成为pDelParent的右孩子,反之则成为左孩子
			if (pDelParent->pLeft == pDelNode)
			{
				pDelParent->pLeft = temp;
			}
			else
			{
				pDelParent->pRight = temp;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小冯爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值