您的位置:首页 > 其它

二叉排序树

2016-03-04 20:38 423 查看
一:概念介绍

二叉排序树又称“二叉查找树”、“二叉搜索树”。

二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:

1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3. 它的左、右子树也分别为二叉排序树。

例如下图就是一个二叉排序树:



二:代码main部分

#include<iostream>  
#include<queue>

using namespace std;

struct Node
{
	int data;
	Node* lChild;
	Node* rChild;
	Node()
	{
		lChild = rChild = nullptr;
		data = 0;
	}
};
class BSTree
{
public:
	Node* root;//根节点
	Node* parent;
	Node* result;
	bool flag;

	BSTree();
	bool SearchBST(Node* _root, int key);  //查找
	bool InsertBST(Node* _root, int key);  //插入
	bool Delete(Node* node);
	bool DeleteBST(Node* _root, int key);  //删除
	void LevelOrder(Node* _root);          //层次遍历
};
int main()
{
	BSTree tree;

	tree.InsertBST(tree.root, 45);
	tree.InsertBST(tree.root, 12);
	tree.InsertBST(tree.root, 53);
	tree.InsertBST(tree.root, 3); tree.InsertBST(tree.root, 3);
	tree.InsertBST(tree.root, 37);
	tree.InsertBST(tree.root, 100);
	tree.InsertBST(tree.root, 24);
	tree.InsertBST(tree.root, 61);
	tree.InsertBST(tree.root, 90); tree.InsertBST(tree.root, 90);
	tree.InsertBST(tree.root, 78);
	
	tree.LevelOrder(tree.root);//层次遍历

	
	tree.DeleteBST(tree.root, 45);
	tree.DeleteBST(tree.root, 61);

	tree.LevelOrder(tree.root);//层次遍历

	return 0;
}


经过12次的数据插入(包括2次重复插入)所构成的排序树为:



经过两次删除所得的输出结果为:



三:函数具体解析

1.初始构造函数

BSTree::BSTree()
{
	root = parent = result = nullptr;
	flag = true;
}


2.查找操作:

bool BSTree::SearchBST(Node* _root, int key)
{
	if(flag)
		parent = result = nullptr;
	if (!_root)                                //查找不成功
	{
		flag = true;
		result = parent;
		return false;
	}
	else if (key == _root->data)               //查找成功
	{
		flag = true;
		result = _root;
		return true;
	}
	else if (key < _root->data)                //左子树查找
	{
		flag = false;
		parent = _root;
		return SearchBST(_root->lChild, key);
	}
	else                                       //右子树查找
	{
		flag = false;
		parent = _root;
		return SearchBST(_root->rChild, key);
	}
}


在根节点_root所指的二叉排序树递归的查找其关键字等于key的数据元素,若查找成功,则指针result指向该元素节点,并返回true;否则指针result指向查找路径上访问的最后一个节点并返回false。指针parent指向result的父母,其中result和parent是定义在类的public成员。

这里要解释一下flag的作用,它是用来标记是否将result和parent恢复初始状态(也就是nullptr)。为什么要恢复呢?因为一个类对象第二次调用查找函数时,它的result和parent还保留着上一次的结果。你可能想到,那也可以不必设置flag啊,直接在每次调用时直接赋值为nullptr不就行了?你忽略了一个事实,该函数是递归函数,每次递归都会恢复初始值。

3.数据插入:

当二叉排序树不存在关键字等于key的数据元素时,插入key并返回true。

bool BSTree::InsertBST(Node* _root, int key)
{
	if (!SearchBST(_root, key))
	{
		Node* p = new Node;
		p->data = key;

		if (!result)//如果是空树
			root = p;
		else if (key < result->data)
			result->lChild = p;
		else
			result->rChild = p;

		return true;
	}

	return false;
}


4.删除操作:

若二叉排序树中存在关键字等于key的数据元素,删除该元素节点

bool BSTree::Delete(Node* node)
{
	if (!node->rChild)//右子树空
	{
		(node->data > parent->data) ? parent->rChild : parent->lChild = node->lChild;
		delete node;
	}
	else if (!node->lChild)//左子树空
	{
		(node->data > parent->data) ? parent->rChild : parent->lChild = node->rChild;
		delete node;
	}
	else//左右子树都不空
	{
		Node* q = node;
		Node* s = node->lChild;
		while (s->rChild)
		{
			q = s;
			s = s->rChild;
		}
		node->data = s->data;
		if (q != node)
			q->rChild = s->lChild;
		else
			q->lChild = s->lChild;
		delete s;
	}

	return true;
}

bool BSTree::DeleteBST(Node* _root, int key)
{
	if (!_root || !SearchBST(_root, key))//空树或不存在key
		return false;
	else
		return Delete(result);
}


5.层次遍历:

void BSTree::LevelOrder(Node* _root)
{
	queue<Node*> q;

	if (!_root) return;//空树直接退出

	q.push(_root);

	while (!q.empty())
	{
		Node* p = q.front();
		q.pop();

		cout << p->data << " ";

		if (p->lChild)
			q.push(p->lChild);
		if (p->rChild)
			q.push(p->rChild);
	}

	cout << endl << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: