关闭

二叉搜索树的插入,删除,查找操作

标签: 二叉树搜索
176人阅读 评论(0) 收藏 举报
分类:
<pre name="code" class="cpp">//头文件
//BinaryTreeNode.h
#ifndef BINARYTREENODE_H
#define BINARYTREENODE_H
template<typename T>
class BinaryTreeNode{
public:
	T data;
	BinaryTreeNode<T>* leftChild;
	BinaryTreeNode<T>* rigthChild;
	BinaryTreeNode<T>* parent;
	BinaryTreeNode(){

	}
	BinaryTreeNode(const T& val, BinaryTreeNode<T>* str, BinaryTreeNode<T>* ptr,BinaryTreeNode<T>* far) :data(val), leftChild(str), rigthChild(ptr),parent(far){

	}
};
#endif
//BinarySearchTree.h
#ifndef BINARYSEARCHTREE_H
#define BINARYSEARCHTREE_H
#include"BinaryTreeNode.h"
#include<iostream>
#include<queue>
#include<string>
using namespace std;
template<typename T>
class BinarySearchTree{
private:
	BinaryTreeNode<T>* root;
	BinaryTreeNode<T>* aim;//要删除的目标指针
private:
	void Clear();
	void CreatTree();
	void InsertNode(BinaryTreeNode<T>* &str, const T& val);
	void PrintIonder()const;
	bool FingVal(const T& val);
	void PrintFindVal(const T& val);
	void DeleteNode(const T& val);
public:
	BinarySearchTree();
	~BinarySearchTree();
	void simulate();
};
template<typename T>
BinarySearchTree<T>::BinarySearchTree()
{
	this->root = NULL;
	this->aim = NULL;
}
template<typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
	this->Clear();
}
template<typename T>
void BinarySearchTree<T>::Clear()
{
	if (this->root)
		return;
	queue<BinaryTreeNode<T>*>node;
	node.push(root);
	while (!node.empty())
	{
		root = node.front();
		node.pop();
		if (root->leftChild)
			node.push(root->leftChild);
		if (root->rigthChild)
			node.push(root->rigthChild);
		delete root;
	}
	root = NULL;
}
template<typename T>
void BinarySearchTree<T>::CreatTree()
{
	queue<T>arr;
	cout << "input the data end of # :";
	string str;
	cin >> str;
	int count = str.length();
	for (int i = 0; str[i]!='#'; i++)
	{
		arr.push(str[i]);
	}
	while (!arr.empty())
	{
		this->InsertNode(this->root, arr.front());
		arr.pop();
	}
}
template<typename T>
void BinarySearchTree<T>::InsertNode(BinaryTreeNode<T>* &str, const T& val)
{
	//插入节点,如果根为空,则生成根节点
	if (root == NULL)
	{
		root = new BinaryTreeNode<T>(val, NULL, NULL,NULL);
		return;
	}
	//否则从根节点开始寻找,如果大于该节点值,则寻找右子树,如果小于则找该节点的左子树
	BinaryTreeNode<T>* ptr = str;
	BinaryTreeNode<T>* prev = NULL;
	while (ptr)
	{
		//该循环的作用是找到一个最后与val有关的节点
		prev = ptr;
		if (ptr->data > val)
			ptr = ptr->leftChild;
		else
			ptr = ptr->rigthChild;
	}
	//开始比较找到的节点的值与给的值的关系,确定要生成的节点的位置
	if (prev->data > val)
	{
		prev->leftChild = new BinaryTreeNode<T>(val, NULL, NULL,prev);
	}
	else if (prev->data < val)
	{
		prev->rigthChild = new BinaryTreeNode<T>(val, NULL, NULL, prev);
	}
	else
		return;
}
template<typename T>
void BinarySearchTree<T>::PrintIonder()const
{
	BinaryTreeNode<T>* str = this->root;
	if (str == NULL)
	{
		cout << "the tree is empty" << endl;
		return;
	}
	queue<BinaryTreeNode<T>*>node;
	node.push(str);
	while (!node.empty())
	{
		str = node.front();
		node.pop();
		if (str->leftChild)
			node.push(str->leftChild);
		if (str->rigthChild)
			node.push(str->rigthChild);
		cout << str->data << " ";
	}
}
template<typename T>
void BinarySearchTree<T>::simulate()
{
	this->CreatTree();
	this->PrintIonder();
	T val;
	cout << "输入你要查找的数据:";
	cin >> val;
	this->PrintFindVal(val);
	cout << "输入你要删除的数据:";
	cin >> val;
	this->DeleteNode(val);
	this->PrintIonder();
}
template<typename T>
bool BinarySearchTree<T>::FingVal(const T& val)
{
	this->aim = this->root;
	if (aim == NULL)
	{
		cout << "the tree is empty" << endl;
		return false;
	}
	while (aim)
	{
		if (aim->data > val)
		{
			aim = aim->leftChild;
		}
		else if (aim->data < val)
		{
			aim = aim->rigthChild;
		}
		else
		{		
			return true;
		}
	}
	return false;
}
template<typename T>
void BinarySearchTree<T>::PrintFindVal(const T& val)
{
	this->aim = NULL;
	bool flag = this->FingVal(val);
	if (!flag)
	{
		cout << "no find" << endl;
		return;
	}
	cout << aim->data <<"查找成功"<< endl;
}
template<typename T>
void BinarySearchTree<T>::DeleteNode(const T& val)
{
	if (!this->FingVal(val))
	{
		cout << "没有找到要删除的节点" << endl;
		return;
	}
	if (this->aim->leftChild == NULL&&this->aim->rigthChild == NULL)
	{
		//要删除的节点没有左右孩子
		BinaryTreeNode<T>* str = this->aim->parent;
		if (str->rigthChild == aim)
		{
			str->rigthChild = NULL;
			delete aim;
		}
		else
		{
			str->leftChild = NULL;
			delete aim;
		}
	}
	else if (this->aim->leftChild != NULL&&this->aim->rigthChild == NULL)
	{
		//要删除的节点只有左孩子,没有右孩子
		BinaryTreeNode<T>* str = this->aim->parent;
		BinaryTreeNode<T>* ptr = this->aim->leftChild;
		if (this->aim == str->rigthChild)
		{
			str->rigthChild = ptr;
			delete aim;
		}
		else
		{
			str->leftChild = ptr;
			delete aim;
		}
	}
	else if (this->aim->leftChild == NULL&&this->aim->rigthChild != NULL)
	{
		//要删除的节点只有右孩子,没有左孩子
		BinaryTreeNode<T>* str = this->aim->parent;
		BinaryTreeNode<T>* ptr = this->aim->rigthChild;
		if (this->aim == str->leftChild)
		{
			str->leftChild = ptr;
			delete aim;
		}
		else
		{
			str->rigthChild = ptr;
			delete aim;
		}
	}
	else
	{
		//该情况是删除的节点左右孩子都存在,还情况下是寻找该节点的右子树中的最小值或者是
		//寻找该节点的左子树中的最大的节点
		BinaryTreeNode<T>* str = this->aim->parent;
		//开始寻找该节点左子树中的最大值
		BinaryTreeNode<T>* ptr = this->aim->leftChild;
		while (ptr->rigthChild)
		{
			ptr = ptr->rigthChild;
		}
		this->aim->data = ptr->data;
		BinaryTreeNode<T>* prev = ptr->parent;
		prev->rigthChild = NULL;
		delete ptr;
	}
}
#endif
//主函数
#include"BinarySearchTree.h"
int main(int argc, char argv[])
{
	BinarySearchTree<char>tree;
	tree.simulate();
	return 0;
}




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20565次
    • 积分:914
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:0篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论