二叉查找树,对于树的每个节点X,它的左子树中的所有关键字值小于X的关键字值,而它的右子树所有关键字值大于X的关键字值。如图,左边是二叉查找树,右边不是。
有以下特性:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值; (3)左、右子树也分别为二叉排序树; 二叉查找树比较麻烦的操作是删除。分别有三种情况: 1.删除节点为子叶,这个直接删除即可。 2.删除节点存在左子树或者右子树,那么直接令这个左子树或者右子树成为该节点的双亲节点的左子树或者右子树。 3.删除节点同时存在左右子树,那么为了保持二叉树的特性,我们必须在其右子树中找到关键字值最小的节点来替代删除的节点。
特点:在二叉查找树中,大部分操作为O(logN).
#pragma once
#include<iostream>
using namespace std;
template<typename T>
struct Node {
T _date;
Node<T> *_left;
Node<T> *_right;
};
template<typename T>
class Bi_Sch_Tree {
typedef struct Node<T> *PtrNode;
public:
Bi_Sch_Tree():T(NULL){}
~Bi_Sch_Tree() {
MakeEmpty(T);
}
void Create(const int *arr, int length) {
for (int i = 0; i < length; ++i)
T = Insert(arr[i], T);
}
PtrNode MakeEmpty(PtrNode root) {
if (root) {
MakeEmpty(root->_left);
MakeEmpty(root->_right);
free(root);
}
return NULL;
}
PtrNode Find(T x, PtrNode root) {
if (!root)
return NULL;
if (x < root->_date)
return Find(x, root->_left);
else if (x > root->_date)
return Find(x, root->_right);
else return root;
}
PtrNode FindMin(PtrNode root) {
if (!root)
return NULL;
if (!root->_left)
return root;
return FindMin(root->_left);
}
PtrNode FindMax(PtrNode root) {
if (!root)
return NULL;
PtrNode p = root;
while (p->_right)
p = p->_right;
return p;
}
PtrNode Insert(T x, PtrNode root) {
if (!root) {
if (!(root = (PtrNode)malloc(sizeof(Node<int>))))
cout << "MALLOC FAIL!" << endl;
else {
root->_date = x;
root->_right = root->_left = NULL;
}
}
else if (x < root->_date)
root->_left = Insert(x, root->_left);
else if (x > root->_date)
root->_right = Insert(x, root->_right);
return root;
}
PtrNode Delete(T x, PtrNode root) {
PtrNode TmpNode;
if (!root)
return NULL;
else if (x < root->_date)
root->_left = Delete(x, root->_left);
else if (x > root->_date)
root->_right = Delete(x, root->_right);
/*左右子树都存在的情况下,右子树最小值替代被删除的的元素*/
else if (root->_left&&root->_right) {
TmpNode = FindMin(root->_right);
root->_date = TmpNode->_date;
root->_right = Delete(TmpNode->_date, root->_right);
}
/*当存在一个子树时*/
else {
TmpNode = root;
if (root->_left)
root = root->_left;
else
root = root->_right;
delete TmpNode;
}
return root;
}
void Pre_Traverse(PtrNode root) {
if (root) {
cout << root->_date << " ";
Pre_Traverse(root->_left);
Pre_Traverse(root->_right);
}
}
PtrNode Get_Root() {
return T;
}
private:
PtrNode T;
};
#include"BinarySearchTree.h"
void main() {
int arr[7] = { 6,2,1,5,3,4,8 };
Bi_Sch_Tree<int> tree;
tree.Create(arr, 7);
Node<int> *p = tree.Get_Root();
cout << "Min:" << tree.FindMin(p)->_date << endl;
cout << "Max:" << tree.FindMax(p)->_date << endl;
tree.Pre_Traverse(p);
cout << endl;
tree.Delete(2, p);
tree.Pre_Traverse(p);
system("pause");
}