BST树
一、BST树的定义:
二叉排序树,二叉搜索树。
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:
- 每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同。
- 左子树(如果存在)上所有结点的关键码都小于根结点的关键码。
- 右子树(如果存在)上所有结点的关键码都大于根结点的关键码。
- 左子树 和右子树也是二叉搜索树。
总结:如果一棵二叉搜索树进行中序遍历,可以按从小到大的顺序,将各个节点关键码排列起来,所以也称二叉搜索树为二叉排序树。
二、结构设计:
2.1二叉树的插入
typedef int KeyType;
typedef struct BstNode
{
KeyType key;
BstNode* leftchild;
BstNode* parent;
BstNode* rightchild;
}BstNode, * BSTree;
BstNode* Buynode()
{
BstNode* s = (BstNode*)malloc(sizeof(BstNode));
if (NULL == s) exit(1);
memset(s, 0, sizeof(BstNode));
return s;
}
BstNode* MakeRoot(KeyType kx)//构建根节点
{
BstNode* s = Buynode();
s->key = kx;
return s;
}
bool Insert(BstNode*& ptr, KeyType kx)
{
BstNode* pa = NULL;
BstNode* p = ptr;
while (p != NULL && p->key != kx)
{
pa = p;
p = kx < p->key ? p->leftchild : p->rightchild;
}
if (p != NULL && p->key == kx) return false;
p = Buynode();
p->key = kx;
p->parent = pa;
if (pa == NULL)
{
ptr = p;
}
else
{
if (p->key < pa->key)
{
pa->leftchild = p;
}
else
{
pa->rightchild = p;
}
}
return true;
}
void InOrder(BstNode* ptr)
{
if (ptr != NULL)
{
InOrder(ptr->leftchild);
cout << ptr->key << " ";
InOrder(ptr->rightchild);
}
}
int main()
{
BSTree root = NULL;
int ar[] = { 53,17,78,9,45,65,87,23,81,94,88,100,23,65 };
int n = sizeof(ar) / sizeof(ar[0]);
for (int i = 0; i < n; ++i)
{
cout << Insert(root, ar[i]) << endl;
}
NiceInOrder(root);
cout << endl;
return 0;
}
2.2查找二叉排序树最小值结点(最左端)
BstNode* First(BstNode* ptr) // Min
{
while (ptr != NULL && ptr->leftchild != NULL)
{
ptr = ptr->leftchild;
}
return ptr;
}
2.3查找当前节点的后继(中序遍历的后继)
BstNode* Next(BstNode* ptr)
{
if (ptr == NULL) return ptr;
if (ptr->rightchild != NULL)
{
return First(ptr->rightchild);
}
else
{
BstNode* pa = ptr->parent;
while (pa != NULL && pa->leftchild != ptr) // pa->rightchild == ptr
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
非递归的中序遍历(正向):
void NiceInOrder(BstNode* ptr)//中序遍历
{
for (BstNode* p = First(ptr); p != NULL; p = Next(p))
{
cout << p->key << " ";
}
cout << endl;
}
2.4查找二叉排序树最后结点
BstNode* Last(BstNode* ptr) // MAX;
{
while (ptr != NULL && ptr->rightchild != NULL)
{
ptr = ptr->rightchild;
}
return ptr;
}
2.5查找当前节点的前驱(中序遍历的前驱)
BstNode* Prev(BstNode* ptr)
{
if (ptr == NULL) return NULL;
if (ptr->leftchild != NULL)
{
return Last(ptr->leftchild);
}
else
{
BstNode* pa = ptr->parent;
while (pa != NULL && pa->rightchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
逆向排序:
void RevNiceInOrder(BstNode* ptr)
{
for (BstNode* p = Last(ptr); p != NULL; p = Prev(p))
{
cout << p->key << " ";
}
cout << endl;
}
2.6删除二叉排序树中的结点
- 可能为空树root=NULL;
- 没找到FindValue not val;
- 找到了Find
1)可能为叶子节点leaf
2)可能为单分支brch
3)可能为双分支two brch——将其转化为单分支或叶子进行删除
4)单根结点(只有左孩子或只有右孩子)
bool Remove(BstNode*& ptr, KeyType kx)
{
if (ptr == NULL) return false;//空树
BstNode* p = ptr;
while (p != NULL && p->key != kx)//没找到
{
p = kx < p->key ? p->leftchild : p->rightchild;
}
if (p == NULL) return false;
if (p->leftchild != NULL && p->rightchild != NULL)//双分支
{
BstNode* last = First(p->rightchild);
p->key = last->key;
p = last;
}
BstNode* pa = p->parent;//叶子或单分支
BstNode* child = p->leftchild != NULL ? p->leftchild : p->rightchild;
if (child != NULL) child->parent = pa;
if (pa == NULL)
{
ptr = child;
}
else
{
if (pa->leftchild == p)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
free(p);
return true;
}