二叉搜索树-非空左子树小于根结点键值,非空右子树大于根结点键值,左右子树均为二叉搜索树。
一、二叉搜索树基本实现
新建一个类BinSeachTree,在BinSeachTree.h中:
#include"iostream"
using namespace std;
#define ElementType int
#define SearchTree TreeNode*
#define Position TreeNode*
class TreeNode {
public:
ElementType element;
SearchTree left;
SearchTree right;
};
class BinSeachTree
{
public:
BinSeachTree();
~BinSeachTree();
SearchTree CreateSearchTree(SearchTree tree);
Position FindFromTree(ElementType x, SearchTree tree);
Position FindMax(SearchTree tree);
Position FindMax2(SearchTree tree);
Position FindMin(SearchTree tree);
Position FindMin2(SearchTree tree);
SearchTree InsertToTree(ElementType x, SearchTree tree);
SearchTree DeleteFromTree(ElementType x, SearchTree tree);
void PreOrderTraversal(SearchTree BT);
SearchTree tree;
};
在BinSeachTree.cpp中:
#include "BinSeachTree.h"
BinSeachTree::BinSeachTree()
{
}
BinSeachTree::~BinSeachTree()
{
}
/*
输入的结构:
30
/ \
20 50
\ / \
25 40 70
/ / \
23 54 80
\
92
*/
SearchTree BinSeachTree::CreateSearchTree(SearchTree tree) { //二叉搜索树的建立
int tree_element;
while (cin >> tree_element) {
if (tree_element == '#')
break;
else
tree = InsertToTree(tree_element, tree);
}
return tree;
}
Position BinSeachTree::FindFromTree(ElementType x, SearchTree tree) { //二叉搜索树查找
if (tree == NULL)
return NULL;
if (tree->element < x)
tree->right = FindFromTree(x, tree->right);
else if (x < tree->element)
tree->left = FindFromTree(x, tree->left);
else
return tree;
}
Position BinSeachTree::FindMax(SearchTree tree) { //二叉搜索树最大结点-非递归
if (tree != NULL)
while (tree->right != NULL)
tree = tree->right;
return tree;
}
Position BinSeachTree::FindMax2(SearchTree tree) { //二叉搜索树最大结点-递归
if (tree == NULL)
return NULL;
else if (tree->right == NULL)
return tree;
else
return FindMax2(tree->right);
}
Position BinSeachTree::FindMin(SearchTree tree) { //二叉搜索树最小结点-非递归
if (tree != NULL)
while (tree->left)
tree = tree->left;
return tree;
}
Position BinSeachTree::FindMin2(SearchTree tree) { //二叉搜索树最小结点-递归
if (tree == NULL)
return NULL;
else if (tree->left == NULL)
return tree;
else
return FindMin(tree->left);
}
SearchTree BinSeachTree::InsertToTree(ElementType x, SearchTree tree) { //二叉搜索树插入-递归
if (tree == NULL) {
SearchTree P = new TreeNode;
if (P == NULL) {
cout << "malloc failed" << endl;
}
else {
P->element = x;
P->left = NULL;
P->right = NULL;
tree = P;
}
}
else if (x < tree->element)
tree->left = InsertToTree(x, tree->left);
else if (x > tree->element)
tree->right = InsertToTree(x, tree->right);
return tree;
}
SearchTree BinSeachTree::DeleteFromTree(ElementType x, SearchTree tree) { //二叉搜索树删除-递归
Position temp;
if (tree == NULL) {
cout << "The tree is empty, no element." << endl;
}
else if (x < tree->element) { //寻找要删除的位置
tree->left = DeleteFromTree(x, tree->left);
}
else if (x > tree->element) { //寻找要删除的位置
tree->right = DeleteFromTree(x, tree->right);
}
else if (tree->left && tree->right) { //找到要删除的位置,该节点有两个孩子
/*temp = FindMin(tree->right);*/ //可以换成左子树最大
temp = FindMax(tree->left);
tree->element = temp->element;
tree->right = DeleteFromTree(tree->element, tree->right);
}
else { //仅有一个子树,或者为叶节点
temp = tree;
if (tree->left == NULL)
tree = tree->right;
else if (tree->right == NULL)
tree = tree->left;
delete temp;
}
return tree;
}
void BinSeachTree::PreOrderTraversal(SearchTree BT) //先序遍历
{
if (BT) {
cout << BT->element << " ";
PreOrderTraversal(BT->left);
PreOrderTraversal(BT->right);
}
}
在main.cpp中:
#include"BinSeachTree.h"
int main()
{
BinSeachTree P ;
P.tree = P.CreateSearchTree(P.tree);
P.PreOrderTraversal(P.tree);
cout << "\n";
cout << "Max is :" << P.FindMax(P.tree)->element << "\n";
cout << "Min is :" << P.FindMin(P.tree)->element << "\n";
P.tree = P.InsertToTree(35, P.tree); P.tree = P.InsertToTree(45, P.tree); P.tree = P.InsertToTree(41, P.tree);
cout << "Insert 35 45 41:";
P.PreOrderTraversal(P.tree);
cout << "\n";
P.tree = P.DeleteFromTree(50, P.tree);
cout << "Delete 50:";
P.PreOrderTraversal(P.tree);
cout << "\n";
system("pause");
return 0;
}
运行结果:
二、二叉搜索树应用-判断是否为同一棵树
新建一个类,在xxx.h中:
#include"iostream"
using namespace std;
#define BBTree BalanceBinTreeNode*
class BalanceBinTreeNode
{
public:
int v;
BBTree Left;
BBTree Right;
int flag;
};
class BalanceBinTree
{
public:
BalanceBinTree();
~BalanceBinTree();
BBTree MakeTree(int N);
BBTree Insert(BBTree T, int V);
BBTree NewNode(int V);
int check(BBTree T, int V);
int Judge(BBTree T, int N);
void ResetT(BBTree T);
void FreeTree(BBTree T);
BBTree BBTPtr;
};
在xxx.cpp中:
#include "BalanceBinTree.h"
/*平衡二叉树平衡因子(任意左右子树的深度之差)小于等于1
这里时比较两个二叉搜索数是否为同一棵树*/
BalanceBinTree::BalanceBinTree()
{
BBTPtr = new BalanceBinTreeNode;
}
BalanceBinTree::~BalanceBinTree()
{
}
/*
输入样例:
4 2 - 一棵树有几点个结点,比较几次
3 1 4 2 -最原始的树
3 4 1 2 -需要比较的第一棵树
3 2 4 1 -需要比较的第二棵树
...下一次比较循环
0 - 退出
*/
BBTree BalanceBinTree::MakeTree(int N) //输入二叉搜索树
{
BBTree T;
int i, V;
cin >> V;
T = NewNode(V);
for (i = 1; i<N; i++) {
cin >> V;
T = Insert(T, V);
}
return T;
}
BBTree BalanceBinTree::Insert(BBTree T,int V) //插入二叉搜索树
{
if (!T) T = NewNode(V);
else {
if (V>T->v)
T->Right = Insert(T->Right, V);
else
T->Left = Insert(T->Left, V);
}
return T;
}
BBTree BalanceBinTree::NewNode(int V)
{
BBTree T = new BalanceBinTreeNode;
T->v = V;
T->Left = T->Right = NULL;
T->flag = 0;
return T;
}
int BalanceBinTree::check(BBTree T, int V)
{
if (T->flag) {
if (V<T->v) return check(T->Left, V);
else if (V>T->v) return check(T->Right, V);
else return 0;
}
else {
if (V == T->v) {
T->flag = 1;
return 1;
}
else return 0;
}
}
int BalanceBinTree::Judge(BBTree T, int N) //判断是否是同一颗二叉搜索树
{
int i, V, flag = 0;
/* flag: 0代表目前还一致, 1代表已经不一致*/
cin >> V;
if (V != T->v) flag = 1;
else T->flag = 1;
for (i = 1; i<N; i++) {
cin >> V;
if ((!flag) && (!check(T, V))) flag = 1;
}
if (flag) return 0;
else return 1;
}
void BalanceBinTree::ResetT(BBTree T) /* 清除T中各结点的flag标记 */
{
if (T->Left) ResetT(T->Left);
if (T->Right) ResetT(T->Right);
T->flag = 0;
}
void BalanceBinTree::FreeTree(BBTree T) /* 释放T的空间 */
{
if (T->Left) FreeTree(T->Left);
if (T->Right) FreeTree(T->Right);
delete T;
}
在main.cpp中:
#include"BalanceBinTree.h"
int main()
{
int N, L, i;
BalanceBinTree T;
cin >> N;
while (N) {
cin >> L;
T.BBTPtr = T.MakeTree(N);
for (i = 0; i<L; i++) {
if (T.Judge(T.BBTPtr, N))cout << "Yes\n";
else cout << "No\n";
T.ResetT(T.BBTPtr); /*清除T中的标记flag*/
}
T.FreeTree(T.BBTPtr);
cin >> N;
}
system("pause");
return 0;
}
运行结果: