二叉搜索树ADT_BSTree

二叉搜索树或是一颗空二叉树, 或是具有以下性质的二叉树:

1.若左子树不为空, 则左子树上所有结点的关键字值均小于根结点的关键字值.

2.若右子树不为空, 则右子树上所有结点的关键字值均大于根结点的关键字值.

3.左右子树也分别是二叉搜索树.

性质: 若以中序遍历一颗二叉搜索树, 将得到一个以关键字值递增排列的有序序列.

1.搜索实现: 若二叉树为空, 则搜索失败. 否则, 将x与根结点比较. 若x小于该结点的值, 则以同样的方法搜索左子树, 不必搜索右子树. 若x

大于该结点的值, 则以同样的方法搜索右子树, 而不必搜索左子树. 若x等于该结点的值, 则搜索成功终止.

search()为递归搜索, search1()为迭代搜索.

2.插入实现: 插入一个新元素时, 需要先搜索新元素的插入位置. 如果树种有重复元素, 返回Duplicate. 搜索达到空子树, 则表明树中不包

含重复元素. 此时构造一个新结点p存放新元素x, 连至结点q, 成为q的孩子, 则新结点p成为新二叉树的根.

3.删除实现: 删除一个元素时, 先搜索被删除结点p, 并记录p的双亲结点q. 若不存在被删除的元素, 返回NotPresent.

(1)若p有两颗非空子树, 则搜索结点p的中序遍历次序下的直接后继结点, 设为s. 将s的值复制到p中.

(2)若p只有一颗非空子树或p是叶子, 以结点p的唯一孩子c或空子树c = NULL取代p.

(3)若p为根结点, 删除后结点c成为新的根. 否则若p是其双亲确定左孩子, 则结点c也应成为q的左孩子, 最后释放结点p所占用的空间.

实现代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
enum ResultCode{ Underflow, Overflow, Success, Duplicate, NotPresent }; // 赋值为0, 1, 2, 3, 4, 5

template <class T>
class DynamicSet
{
public:
	virtual ~DynamicSet() {}
	virtual ResultCode Search(T &x) const = 0;
	virtual ResultCode Insert(T &x) = 0;
	virtual ResultCode Remove(T &x) = 0;
	/* data */
};

template <class T>
struct BTNode
{
	BTNode() { lChild = rChild = NULL; }
	BTNode(const T &x) {
		element = x;
		lChild = rChild = NULL;
	}
	BTNode(const T &x, BTNode<T> *l, BTNode<T> *r) {
		element = x;
		lChild = l;
		rChild = r;
	}
	T element;
	BTNode<T> *lChild, *rChild;
	/* data */
};

template <class T>
class BSTree : public DynamicSet<T>
{
public:
	explicit BSTree() { root = NULL; } // 只可显示转换
	virtual ~BSTree() { Clear(root); }
	ResultCode Search(T &x) const;
	ResultCode Search1(T &x) const;
	ResultCode Insert(T &x);
	ResultCode Remove(T &x);
protected:
	BTNode<T> *root;
private:
	void Clear(BTNode<T> *t);
	ResultCode Search(BTNode<T> *p, T &x) const;
	/* data */
};

template <class T>
void BSTree<T>::Clear(BTNode<T> *t)
{
	if(t) {
		Clear(t -> lChild);
		Clear(t -> rChild);
		cout << "delete" << t -> element << "..." << endl;
		delete t;
	}
}

template< class T>
ResultCode BSTree<T>::Search(T &x) const
{
	return Search(root, x);
}
template <class T>
ResultCode BSTree<T>::Search(BTNode<T> *p, T &x) const
{
	if(!p) return NotPresent;
	if(x < p -> element) return Search(p -> lChild, x);
	if(x > p -> element) return Search(p -> rChild, x);
	x = p -> element;
	return Success;
}

template <class T>
ResultCode BSTree<T>::Search1(T &x) const
{
	BTNode<T> *p = root;
	while(p) {
		if(x < p -> element) p = p -> lChild;
		else if(x > p -> element) p = p -> rChild;
		else {
			x = p -> element;
			return Success;
		}
	}
	return NotPresent;
}

template <class T>
ResultCode BSTree<T>::Insert(T &x)
{
	BTNode<T> *p = root, *q = NULL;
	while(p) {
		q = p;
		if(x < p -> element) p = p -> lChild;
		else if(x > p -> element) p = p -> rChild;
		else {
			x = p -> element;
			return Duplicate;
		}
	}
	p = new BTNode<T>(x);
	if(!root) root = p;
	else if(x < q -> element) q -> lChild = p;
	else q -> rChild = p;
	return Success;
}

template <class T>
ResultCode BSTree<T>::Remove(T &x)
{
	BTNode<T> *c, *s, *r, *p = root, *q = NULL;
	while(p && p -> element != x) {
		q = p;
		if(x < p -> element) p = p -> lChild;
		else p = p -> rChild;
	}
	if(!p) return NotPresent;
	x = p -> element;
	if(p -> lChild && p -> rChild) {
		s = p -> rChild;
		r = p;
		while(s -> lChild) {
			r = s;
			s = s -> lChild;
		}
		p -> element = s -> element;
		p = s;
		q = r;
	}
	if(p -> lChild) c = p -> lChild;
	else c = p -> rChild;
	if(p == root) root = c;
	else if(p == q -> lChild) q -> lChild = c;
	else q -> rChild = c;
	delete p;
	return Success;
}
int main(int argc, char const *argv[])
{
	BSTree<int> bst;
	int x = 28; bst.Insert(x);
	x = 21; bst.Insert(x);
	x = 25; bst.Insert(x);
	x = 36; bst.Insert(x);
	x = 33; bst.Insert(x);
	x = 43; bst.Insert(x);
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 16:01:10

二叉搜索树ADT_BSTree的相关文章

用JS实现二叉搜索树

二叉树的节点最多只能有两个子节点,一个左侧子节点,一个右侧子节点. 二叉搜索树(BST),是二叉树的一种,但只允许在左侧节点存储比父节点小的值,在右侧节点存储比父节点大或等于父节点的值. 1.创建BST 1.1创建BST类 首先申明BST类的基本结构 function BinarySearchTree() { var Node = function(key){ this.key = key; this.left = null; this.right = null; }; var root = n

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

二叉搜索树

#include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> using namespace std; struct TreeNode { TreeNode* p; TreeNode* l; TreeNode* r; int key; TreeNode() { p = 0; l = 0; r = 0; key = -1; } }; const int RANDMOD = 30

04-树4 是否同一棵二叉搜索树

给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果.于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树. 输入格式: 输入包含若干组测试数据.每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数.第2行给出N个以空格分隔的正整数,作为初始插入序列.最后L行,每行给出N个插入的元素,属于

二叉搜索树建立、插入、删除、前继节点、后继节点之c++实现

一.前言 一直以来,都对树有关的东西望而却步.以前每次说要看一看,都因为惰性,时间就那么荒废掉了.今天下个决心,决定好好的数据结构中的东西看一下.不知道看这篇文章的你,是不是和我有同样的感受,空有一颗努力的心,却迟迟没有付出行动.如果是的话,如果也想好好的把树的知识巩固一下的话,就让我们一起好好儿地把知识点过一遍吧.本文争取让看完的每一个没有基础的同学,都能有所收获.在正文开始前,先给自己加个油.加油(^ω^) 二.二叉搜索树的定义 二叉搜索树是指,对于某一个节点而言,它左边的节点都小于或等于它

剑指offer:二叉搜索树与双向链表

1.题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2.解题思路: (1)将左子树构造成双向链表,并返回链表头节点: (2)定位左子树双链表的尾节点: (3)如果左子树链表不为空,将当前root连缀其链尾: (4)将右子树构造出双向链表,并返回链表头节点: (5)如果右子树链表不为空,将当前root连缀其表头: (6)根据左子树链表是否为空,确定返回的节点. 3.JavaScript实现: function Conv

数据结构——二叉搜索树、B树、B-树

数据结构——二叉搜索树.B树.B-树 1. 综述 二叉排序树(Binary Sort Tree),又叫二叉查找树(Binary Search Tree),也叫二叉排序树. 二叉搜索树满足以下性质: 1. 若根节点左子树不为空,则左子树上的所有节点均小于根节点: 2. 若根节点右子树不为空,则右子树上的所有节点均大于根节点: 3. 其左右子树也是二叉搜索树(递归定义): 4. 没有键值相等的点. B树就是B-树.B树/B-树英文叫B-Tree,可能被不小心翻译成了B-树.

PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)

L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数N:第二行给出N个互不相同的正整数,其间以空格分隔. 输出格式: 将输入的N个正整数顺序插入一个初始为空的二叉搜索树.在第一行中输出结果树的层序

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable