每个结点都有一个作为搜索依据的关键码
左子树上所有结点值小于根节点的值,右子树上所有结点值大于根结点的值
如果对一棵二叉搜索树进行中序遍历,可以按从小到大的顺序将各节点的值排列起来
typedef struct BstNode
{
KeyType key;
BstNode* leftchild;
BstNode* parent;
BstNode* rightchild;
}BstNode,*BSTree;
BstNode* Buynode(KeyType kx)
{
BstNode*s = (BstNode*)malloc(sizeof(BstNode));
if (nullptr == s){ exit(1); }
memset(s, 0, sizeof(BstNode));
s->key = kx;
return s;
}
void Freenode(BstNode *p)
{
free(p);
}
//查询,递归
BstNode*SearchValue(BstNode* ptr, KeyType kx)
{
if (ptr == nullptr || ptr->key == kx)
{
return ptr;
}
else if (kx < ptr->key)
{
return SearchValue(ptr->leftchild, kx);
}
else
{
return SearchValue(ptr->rightchild, kx);
}
}
//查询,非递归
BstNode*FindValue(BstNode* ptr, KeyType kx)
{
while (ptr != nullptr&&ptr->key != kx)
{
ptr = kx < ptr->key ? ptr->leftchild : ptr->rightchild;
}
return ptr;
}
//节点的插入(构建排序二叉树的过程)
bool Insert(BstNode*&ptr,KeyType kx)
{
if (ptr == nullptr)
{
ptr = Buynode(kx);//如果没有引用。ptr指向节点,不代表root指向节点
return true;
}
BstNode* pa = nullptr;//双亲
BstNode* p = ptr;//ptr是根,不能直接改变。p为当前的节点
while (p != nullptr&&p->key != kx)
{
pa = p;
p = kx < p->key ? p->leftchild : p->rightchild;
}
//原树中已经存在这个节点
if (p != nullptr&&p->key == kx)
{
return false;
}
p = Buynode(kx);
p->parent = pa;
if (p->key < pa->key)
{
pa->leftchild = p;
}
else
{
pa->rightchild = p;
}
return true;
}
//中序遍历
void InOrder(BstNode* ptr)
{
if (ptr != nullptr)
{
InOrder(ptr->leftchild);
cout << ptr->key << " ";
InOrder(ptr->rightchild);
}
}
//树的最左,中序遍历的第一个节点,min
BstNode* First(BstNode* ptr)
{
while (ptr != nullptr&&ptr->leftchild != nullptr)
{
ptr = ptr->leftchild;
}
return ptr;
}
//树的最右,中序遍历的最后一个节点,max
BstNode* Last(BstNode* ptr)
{
while (ptr != nullptr&&ptr->rightchild != nullptr)
{
ptr = ptr->rightchild;
}
return ptr;
}
//不使用栈和队列的非递归中序遍历
//找到第一个值,依次打印后继
//
void NiceInOrder(BstNode *ptr)
{
for (BstNode* p = First(ptr); p != nullptr; p = Next(p))
{
cout << p->key << " ";
}
cout << endl;
}
//判断树是不是排序二叉树。思路:排序二叉树的中序遍历有序
//使用非递归方式
bool Is_BST(BstNode* ptr)
{
bool res = true;
if (ptr == nullptr)return res;
BstNode* pre = nullptr;
std::stack<BstNode*>st;
//找最左
while (ptr != nullptr || !st.empty())
{
while (ptr != nullptr)
{
st.push(ptr);
ptr = ptr->leftchild;
}
ptr = st.top(); st.pop();
//和前驱节点进行比较
if (pre != nullptr&&pre->key >= ptr->key)
{
res = false;
break;
}
pre = ptr;
ptr = ptr->rightchild;
}
return res;
}
//直接前驱(左孩子的最右)
BstNode* Prev(BstNode* ptr)
{
while (ptr != nullptr&&ptr->rightchild != nullptr)
{
ptr = ptr->rightchild;
}
return ptr;
}
//直接后继(右孩子的最左)
BstNode* Next(BstNode* ptr)
{
while (ptr != nullptr&&ptr->leftchild != nullptr)
{
ptr = ptr->leftchild;
}
return ptr;
}
bool Remove(BstNode*& ptr, KeyType kx)
{
bool res = false;
if (ptr == nullptr) return res;
BstNode* p = ptr;
while (p != nullptr&&p->key != kx)
{
p = kx < p->key ? p->leftchild : p->rightchild;
}
if (p == nullptr) return false;
//双分支
if (p->leftchild != nullptr&&p->rightchild != nullptr)
{
BstNode* nt = Next(p->rightchild);//找直接后继,即右孩子的最左
p->key = nt->key;
p = nt;
}
BstNode* pa = p->parent;
BstNode* child = p->leftchild != nullptr ? p->leftchild : p->rightchild;
if (child != nullptr) child->parent = pa;
if (pa == nullptr)
{
ptr = child;
}
else
{
//child为空,说明是叶子节点
if (pa->leftchild == p)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
Freenode(p); p = nullptr;
return true;
}
int main()
{
BSTree root = nullptr;
vector<int> ar = { 53, 17, 78, 9, 45, 65, 87, 23, 81, 94, 88, 92 };
for (auto& x : ar)
{
Insert(root, x);
}
InOrder(root);
cout << endl;
bool res = Is_BST(root);
cout << res << endl;
int x;
while (cin >> x, x != -1)
{
Remove(root, x);
InOrder(root);
cout << endl;
}
return 0;
}