当前位置: 首页 > news >正文

二叉搜索树

二叉搜索树

  • 二叉搜索树结构
  • 二叉搜索树插入
  • 二叉搜索树的查找
  • 二叉搜索树的删除
  • 二叉搜索树中序便利
  • 二叉搜索树默认成员函数实现


二叉搜索树结构


template<class K, class V>
class BinarySeacherTreeNode
{
public:
	BinarySeacherTreeNode(K Key = new K, V Val = new V) :left(NULL), right(NULL), key(Key), val(Val) {}

	BinarySeacherTreeNode* left;
	BinarySeacherTreeNode* right;
	K key;
	V val;
};
template<class K, class V>
class BinarySeacherTree
{
public:
	using Node = BinarySeacherTreeNode<K, V>;
private:
	Node* head = NULL;

二叉搜索树插入


插入思路:
定义一个cur指针和一个parent指针;插入的key比cur指向的key大就往右边走cur走一次parent跟新知道cur为空此时判断parent的key和要插入的key的大小来决定插入左边还是右边

bool Insert(const K& key, const V& val)
{
	if (head == NULL)
	{
		head = new Node(key, val);
		return true;
	}
	Node* parent = head;
	Node* cur = head;
	while (cur)
	{
		if (key > cur->key)
		{
			parent = cur;
			cur = cur->right;
		}
		else if (key < cur->key)
		{
			parent = cur;
			cur = cur->left;
		}
		else
		{
			return false;
		}
	}
	//上面循环就是找到插入的父节点
	//下面还要判断插入父节点的左右孩子
	cur = new Node(key, val);
	if (parent->key < key)
	{
		parent->right = cur;
	}
	else
	{
		parent->left = cur;
	}
	return true;
}


二叉搜索树的查找


查找思路:
如果查找的key大于当前节点的key就去右边反之左边,相等返回该节点
直到cur为空还没找到就返回空指针

Node* Find(const K& key)
{
	Node* cur = head;
	while (cur)
	{
		if (cur->key < key)
		{
			cur = cur->right;
		}
		else if (cur->key > key)
		{
			cur = cur->left;
		}
		else
		{
			return cur;
		}
	}
	//cout << "找不到" << endl;
	return NULL;
}

二叉搜索树的删除


删除思路:

  1. 先找到要删除的节点
  2. 判断要删除的节点有结构孩子
  1. 删除的节点有一个或一个孩子
    该情况如下:
    在这里插入图片描述
    至于0个孩子节点可以看做有一个空节点进行处理
    我们找到只需要把parent指向cur的孩子这里还要进行判断首先就是看cur是parent的左孩子还是右孩子,之后在判断cur的那一个孩子是哪一个最后进行连接即可
    注意:
    这时候我们要考虑删除的是根节点的话我们直接改变根节点的指向就可以了
  2. 删除的节点有两个节点
    该情况如下:
    在这里插入图片描述
    此时我们要进行代替法就是找cur的右树中最左端的节点或者左子树最右端的节点交换里面的值然后删除代替的那个节点即可
bool Erase(const K& key)
{
	Node* cur = head;
	Node* parent = head;
	while (cur)
	{
		if (key > cur->key)
		{
			parent = cur;
			cur = cur->right;
		}
		else if (key < cur->key)
		{
			parent = cur;
			cur = cur->left;
		}
		else
		{
			//1.删除的节点有2个孩子
			if (cur->left && cur->right)
			{
				//去右树找找左的节点来代替然后析构该节点
				Node* replaceparent = cur;
				Node* replace = cur->right;
				while (replace->left)
				{
					replaceparent = replace;
					replace = replace->left;
				}
				cur->val = replace->val;
				if (replaceparent->right == replace)
				{
					replaceparent->right = replace->right;
					delete replace;
					replace = NULL;
				}
				else
				{
					replaceparent->left = replace->right;
					delete replace;
					replace = NULL;
				}
			}
			//2.删除的节点有0或1个孩子
			else
			{
				//如果删除的是根节点直接跟新我们的根节点
				if (cur == head)
				{
					if (cur->left) head = cur->left;
					else head = cur->right;
				}
				else
				{
					if (parent->left == cur)
					{
						if (cur->left) parent->left = cur->left;
						else parent->left = cur->right;
					}
					else
					{
						if (cur->left) parent->right = cur->left;
						else parent->right = cur->right;
					}
				}
			}
			return true;
		}
	}
	return false;
}


二叉搜索树中序便利


void InOrder()
{
	_inorder(head);
}
void _inorder(Node* head)
{
	if (head == NULL)return;
	_inorder(head->left);
	cout << "key:" << head->key << " val:" << head->val << " ";
	_inorder(head->right);
}

二叉搜索树默认成员函数实现


拷贝构造函数:

BinarySeacherTree(const BinarySeacherTree& b)
{
	this->head = createtree(b.head);
}
Node* createtree(Node* hea)
{
	if (hea == NULL) return nullptr;
	Node* root = new Node(hea->key, hea->val);
	root->left = createtree(hea->left);
	root->right = createtree(hea->right);
	return root;
}

赋值重载:

BinarySeacherTree<K, V> operator=( BinarySeacherTree<K, V> tem)
{
	//这里参数不要传入引用
	std::swap(head, tem.head);
	return *this;
}

析构函数:

~BinarySeacherTree()
{
	destory(head);
	head = NULL;
}
void destory(Node* hea)
{
	if (hea == NULL)return;
	destory(hea->left);
	destory(hea->right);
	delete hea;
	hea = NULL;
}

相关文章:

  • 零基础如何学会Appium自动化测试?
  • ESP8266+httpServer+GET+POST实现网页验证密码
  • 王者荣耀改重复名(java源码)
  • 在线IP代理检测:保护您的网络安全
  • LineageOS连接网络提示IP配置失败
  • Maven的高级特性
  • 【数学建模】2024数学建模国赛经验分享
  • 在Java中,==和equals的区别,以及重写equals()方法还要重写hashCode()方法
  • 计算机知识科普问答--12 (56-60)
  • 【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新
  • 使用Microsoft Visual Studio Installer Projects 2022打包桌面程序
  • NoSQL数据库实战派
  • springboot实战学习笔记(2)
  • Thinkphp5 + Swoole实现邮箱异步通知
  • 【Linux 从基础到进阶】Docker 容器技术基础与应用
  • 【两方演化博弈代码复现】:双方演化博弈的原理、概率博弈仿真、相位图、单个参数灵敏度演化
  • Unity程序基础框架
  • pytest 接口测试
  • 深度挖掘| 如何高效实现Cloudera 安装之基础环境搭建
  • Web3入门指南:从基础概念到实际应用
  • 习近平出席中国-拉美和加勒比国家共同体论坛第四届部长级会议开幕式并发表重要讲话
  • 超新星|罚丢点球的那道坎,刘诚宇靠自己迈了过去
  • 美国“贸易战”前线的本土受害者:安静的洛杉矶港和准备关门的小公司
  • 欧阳娜娜携家人回江西探亲,受聘为江西吉安文化旅游大使
  • 《三餐四季》广东篇今晚开播:食在岭南,遇见百味
  • 外交部发言人就印巴局势升级答记者问