二叉排序树:左子树上所有结点的值均小于它根结点的值,右子树上所有结点的值均大于它根结点的值,它的左、右树又分为⼆叉排序树。二叉排序树中序遍历为递增。
#include<iostream>
#include<assert.h>
using namespace std;
typedef int KeyType;
typedef struct BstNode
{
BstNode* leftchild;
BstNode* rightchild;
BstNode* parent;
KeyType key;
}BstNode;
typedef struct
{
BstNode* root;
int cursize;
}BstTree;
BstNode* BuyNode()
{
BstNode* ptr = (BstNode*)calloc(1, sizeof(BstNode));
if (ptr == nullptr) exit(EXIT_FAILURE);
return ptr;
}
void FreeNode(BstNode* ptr)
{
free(ptr);
}
void InitTree(BstTree* ptree)
{
assert(ptree != nullptr);
ptree->root = nullptr;
ptree->cursize = 0;
}
//非递归查询
BstNode* FindValue(BstTree* ptree, KeyType kx)
{
BstNode* ptr = ptree->root;
while (ptr != nullptr && ptr->key != kx)
{
ptr = kx < ptr->key ? ptr->leftchild : ptr->rightchild;
}
return ptr;
}
//递归查询
BstNode* Search(BstNode* ptr, KeyType kx)
{
if (ptr == nullptr || ptr->key == kx)return ptr;
else if (kx < ptr->key) return Search(ptr->leftchild, kx);
else return Search(ptr->rightchild, kx);
}
BstNode* SearchValue(BstTree* ptree, KeyType kx)
{
return Search(ptree->root, kx);
}
//插入
bool Insert_Item(BstTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
if (ptree->root == nullptr)
{
ptree->root = BuyNode();
ptree->root->key = kx;
ptree->cursize = 1;
return true;
}
BstNode* ptr = ptree->root, * pa = nullptr;
while (ptr != nullptr && ptr->key != kx)
{
pa = ptr;
ptr = kx < ptr->key ? ptr->leftchild : ptr->rightchild;
}
if (ptr != nullptr && ptr->key == kx) return false;
ptr = BuyNode();
ptr->key = kx;
ptr->parent = pa;
if (kx < pa->key)
{
pa->leftchild = ptr;
}
else
{
pa->rightchild = ptr;
}
ptree->cursize += 1;
return true;
}
//中序遍历
void InOrder(BstNode* ptr)
{
if (ptr != nullptr)
{
InOrder(ptr->leftchild);
printf("%3d", ptr->key);
InOrder(ptr->rightchild);
}
}
void InOrder(BstTree* ptree)
{
assert(ptree != nullptr);
InOrder(ptree->root);
printf("\n");
}
//返回中序遍历第一个结点
BstNode* First(BstNode* ptr)
{
/*if (ptr == nullptr) return nullptr;
if (ptr->leftchild == nullptr) return ptr;
else return First(ptr->leftchild);*/
while (ptr != nullptr && ptr->leftchild != nullptr)
{
ptr = ptr->leftchild;
}
return ptr;
}
//返回中序遍历结点的下一个结点
BstNode* Next(BstNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->rightchild != nullptr)
{
return First(ptr->rightchild);
}
else
{
BstNode* pa = ptr->parent;
while (pa != nullptr && pa->leftchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
//非递归中序遍历
void NiceInOrder(BstTree* ptree)
{
assert(ptree != nullptr);
for (BstNode* ptr = First(ptree->root); ptr != nullptr; ptr = Next(ptr))
{
printf("%3d", ptr->key);
}
printf("\n");
}
//返回中序遍历最后一个结点
BstNode* Last(BstNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->rightchild == nullptr) return ptr;
else return Last(ptr->rightchild);
}
//返回中序遍历结点的上一个结点
BstNode* Prev(BstNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->leftchild != nullptr)
{
return Last(ptr->leftchild);
}
else
{
BstNode* pa = ptr->parent;
while (pa != nullptr && pa->rightchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
//非递归反向中序遍历
void ResNiceInOrder(BstTree* ptree)
{
assert(ptree != nullptr);
for (BstNode* ptr = Last(ptree->root); ptr != nullptr; ptr = Prev(ptr))
{
printf("%3d", ptr->key);
}
printf("\n");
}
//删除结点
bool Remove_Item(BstTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
if (ptree->root == nullptr) return false;
BstNode* ptr = FindValue(ptree, kx);
if (ptr == nullptr) return false;
if (ptr->leftchild != nullptr && ptr->rightchild != nullptr)
{
BstNode* subnode = Next(ptr);
ptr->key = subnode->key;
ptr = subnode;
}
BstNode* child = ptr->leftchild != nullptr ? ptr->leftchild : ptr->rightchild;
BstNode* pa = ptr->parent;
if (child != nullptr) child->parent = pa;//说明ptr为单分支
if (pa != nullptr)//判断ptr是否为单根
{
if (pa->leftchild == ptr)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
else
{
ptree->root = child;
}
FreeNode(ptr);
ptree->cursize -= 1;
return true;
}
int main()
{
BstTree tree = { 0 };
KeyType ar[] = { 53,17,78,9,45,65,87,23,81,94,88,17 };
InitTree(&tree);
int len = sizeof(ar) / sizeof(ar[0]);
for (int i = 0; i < len; ++i)
{
printf("%3d", Insert_Item(&tree, ar[i]));
}
printf("\n");
InOrder(&tree);
NiceInOrder(&tree);
ResNiceInOrder(&tree);
KeyType kx;
while (scanf_s("%d", &kx), kx != -1)
{
printf("%d\n", Remove_Item(&tree, kx));
NiceInOrder(&tree);
}
return 0;
}