二叉搜索树
#include <iostream>
using namespace std;
typedef int Datatype;
typedef struct TreeNode *BinTree;
struct TreeNode
{
Datatype data;
BinTree Left;
BinTree Right;
};
//创建
BinTree CreateBinarySerachTree()
{
BinTree BST = new TreeNode;
BST = NULL;
return BST;
}
//查找递归实现
BinTree Find(Datatype X, BinTree BST)
{
if (!BST)//为空返回NULL
return NULL;
else if (X < BST->data)//比根节点小递归左边
return Find(X, BST->Left);
else if (X > BST->data)//比根节点大递归右边
return Find(X, BST->Right);
else if (X == BST->data)//找到值
return BST;
}
//查找非递归实现
BinTree NonrecurFind(Datatype X, BinTree BST)
{
while (BST)//根结点不空
{
if (X < BST->data)
BST = BST->Left;
else if (X > BST->data)
BST = BST->Right;
else if (X == BST->data)
return BST;
}
return NULL;
}
//查找最小值递归实现
BinTree FindMin(BinTree BST)
{
if (!BST)//根节点为空返回NULL
return NULL;
else if (BST->Left)//左子树不空,递归左边
return FindMin(BST->Left);
else//左边空返回当前根节点
return BST;
}
//查找最大值非递归实现
BinTree FindMax(BinTree BST)
{
if (!BST)
return NULL;
else
while (BST->Right)
BST = BST->Right;
return BST;
}
//插入
BinTree Insert(Datatype X, BinTree BST)
{
if (!BST)//如果当前根节点空,进行初始化
{
BST = new TreeNode;
BST->data=X;
BST->Left = NULL;
BST->Right = NULL;
}
else {//如果不空
if (X < BST->data)//如果小,挂左边
BST->Left = Insert(X, BST->Left);
else if (X > BST->data)//如果大挂右边
BST->Right = Insert(X, BST->Right);
//如果相等不用管
}
return BST;
}
//删除
/*删除的三种情况:
1.要删除的是叶结点:直接删除,并将其父结点指针指向 NULL
2.要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
3.要删除的结点有左、右两棵子树:用右子树的最小元素或左子树的最大元素替代被删除结点*/
BinTree Delete(Datatype X, BinTree BST)
{
BinTree tmp;
if (!BST)
cout << "要删除的元素未找到"<<endl;
else if (X < BST->data) // X 比当前结点值小,在左子树继续查找删除
BST->Left = Delete(X, BST->Left);
else if (BST->data < X) // X 比当前结点值大,在右子树继续查找删除
BST->Right = Delete(X, BST->Right);
else//找到该值
{
if (BST->Left && BST->Right)//有左右两个结点
{
tmp = FindMin(BST->Right);//找到右子树中最小的值的结点
BST->data = tmp->data;//用右子树中最小值替换
BST->Right = Delete(tmp->data, BST->Right);//删除右子树中最小值的结点
}
else//有一个结点或没有结点
{
tmp = BST;
if (!BST->Left && !BST->Right)//没有结点
BST = NULL;
else if (BST->Left && !BST->Right)//只有左结点
BST = BST->Left;
else if (!BST->Left && BST->Right)//只有右结点
BST = BST->Right;
delete tmp;
tmp = NULL;
}
}
return BST;
}
//中序遍历
void InOrederTrasersal(BinTree BST)
{
if (BST)
{
InOrederTrasersal(BST->Left);
cout << BST->data << " ";
InOrederTrasersal(BST->Right);
}
}
int main()
{
BinTree BST=NULL;
int i;
cout << "1.创建; 2.查找; 3.查找最小值; 4.查找最大值; 5.插入; 6.删除; 7.中序遍历; 0.退出" << endl;
do
{
cout << "输入操作:";
cin >> i;
switch (i)
{
case 0:break;
case 1:BST = CreateBinarySerachTree(); break;
case 2:
Datatype X;
BinTree tmp1,tmp2;
cout << "输入查找值:";
cin >> X;
if (!Find(X, BST))
{
cout << "未找到该值" << endl;
break;
}
tmp1=Find(X, BST);
tmp2 = NonrecurFind(X, BST);
cout << "该值为(递归):" << tmp1->data << " "<< endl;
cout << "该值为(非递归):" << tmp2->data << " "<< endl;
break;
case 3:
BinTree tmp3;
if (!FindMin(BST))
{
cout << "未找到该值"<<endl;
break;
}
tmp3 = FindMin(BST);
cout << "最小值为:" << tmp3->data << endl;
break;
case 4:
BinTree tmp4;
if (!FindMax(BST))
{
cout << "未找到该值"<<endl;
break;
}
tmp4 = FindMax(BST);
cout << "最大值为:" << tmp4->data << endl;
break;
case 5:
Datatype Y;
cout << "输入插入的值:";
cin >> Y;
BST = Insert(Y, BST);
break;
/*
5
/\
3 7
/\ /\
1 4 6 8
\ \
2 9
*/
case 6:
Datatype Z;
cout << "输入删除的值:";
cin >> Z;
BST = Delete(Z, BST);
break;
case 7:
cout << "中序遍历:";
InOrederTrasersal(BST);
cout << endl;
break;
default:cout << "输入错误,请重新"; break;
}
} while (i != 0);
return 0;
}
运行:
AVL:
#include <iostream>
using namespace std;
typedef struct AVLNode* AVLTree;
struct AVLNode
{
int data;
AVLTree left;
AVLTree right;
int height;
};
int Max(int a, int b)
{
return a > b ? a : b;
}
int GetHeight(AVLTree A)
{
return A == NULL ? -1 : A->height;
}
//LL单旋(破坏平衡结点在根节点左子树的左子树)
//将B的右子树连接到A的左子树下,将A连接到B的右子树下,返回B为根结点
AVLTree LLRotation(AVLTree A)
{
AVLTree B=A->left;//声明B为A的左子树
A->left = B->right;
B->right = A;
A->height = Max(GetHeight(A->left), GetHeight(A->right)) + 1;
B->height = Max(GetHeight(B->left), A->height) + 1;
return B;
}
//RR单旋(与LL单旋相反)
AVLTree RRRotation(AVLTree A)
{
AVLTree B = A->right;
A->right = B->left;
B->left = A;
A->height = Max(GetHeight(A->left), GetHeight(A->right)) + 1;
B->height = Max(GetHeight(B->right), A->height) + 1;
return B;
}
//LR双旋(破坏结点在根节点左子树的右子树)
//先将B作为根节点进行RR单旋,再将A作为根节点进行LL单旋
AVLTree LRRotation(AVLTree A)
{
A->left = RRRotation(A->left);
return LLRotation(A);
}
//RL双旋(与LR双旋相反)
AVLTree RLRotation(AVLTree A)
{
A->right = LLRotation(A->right);
return RRRotation(A);
}
//按二叉搜索树插入,边插入边调整成平衡二叉树
AVLTree Insert(AVLTree T, int x)
{
if (!T)//T为空
{
T = new AVLNode;
T->data = x;
T->left = NULL;
T->right = NULL;
T->height = 0;
}
else
{
if (x < T->data)//插入左边
{
T->left = Insert(T->left, x);
if (GetHeight(T->left) - GetHeight(T->right) == 2)
{
if (x < T->left->data)//插在左子树的左子树,LL单旋
T=LLRotation(T);
else if (x > T->left->data)//插在左子树的右子树,LR双旋
T=LRRotation(T);
}
}
else if (x > T->data)//插入右边
{
T->right = Insert(T->right, x);
if (GetHeight(T->left) - GetHeight(T->right) == 2)
{
if (x > T->right->data)
T=RRRotation(T);
else if (x < T->right->data)
T=RLRotation(T);
}
}
}
//更新树高
T->height = Max(GetHeight(T->left), GetHeight(T->right)) + 1;
return T;
}
int main()
{
AVLTree T=NULL;
int n,data;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> data;
T=Insert(T, data);
}
cout << T->data;
return 0;
}