二叉搜索树
概念:
二叉查找树,它或者是一棵空树,或者是具有下列性质的 二叉树 : 若它的左子树不空,则左子树上所有结点的值均小于它的 根结点 的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为 二叉排序树 。
所需头文件:
#include<iostream>
#include<stdlib.h>
#include<malloc.h>
using namespace std;
结构体设计:
typedef struct BstNode
{
struct BstNode* leftchild;
struct BstNode* rightchild;
struct BstNode* parent;
int key;
}BstNode;
typedef struct BsTree
{
BstNode* root;
int cursize;
}BsTree;
初始化二叉搜索树:
void InitTree(BsTree* ptree)
{
ptree->root = NULL;
ptree->cursize = 0;
}
插入元素(构建二叉搜索树):
思路:
①先判断有无根节点,若无根节点,则直接让新插入元素成为根节点
②有根节点则直接找到合适位置并插入
BstNode* BuyNode()
{
BstNode* node = (BstNode*)calloc(1, sizeof(BstNode) * 1);
if (node == NULL)
{
exit(1);
}
return node;
}
void Insert_Item(BsTree* ptree, const int kx)
{
BstNode* ptr = ptree->root;
BstNode* pa = NULL;
while (ptr != NULL && ptr->key != kx)
{
pa = ptr;
ptr = kx > pa->key ? ptr->rightchild : ptr->leftchild;
}
if (ptr != NULL && ptr->key == kx) //已经存在这个值
{
return;
}
ptr = BuyNode();
ptr->key = kx;
ptr->parent = pa;
if (pa == NULL)
{
ptree->root = ptr;
}
else
{
if (ptr->key > pa->key)
{
pa->rightchild = ptr;
}
else
{
pa->leftchild = ptr;
}
}
ptree->cursize += 1;
}
First函数(获取该树在中序遍历中的第一个元素并返回):
BstNode* First(BstNode* ptr)
{
while (ptr != NULL && ptr->leftchild != NULL)
{
ptr = ptr->leftchild;
}
return ptr;
}
Next函数(获取该节点在中序遍历中的下一个元素并返回):
BstNode* Next(BstNode* ptr)
{
if (ptr->rightchild != NULL)
{
return First(ptr->rightchild);
}
else
{
BstNode* pa = ptr->parent;
while (pa != NULL && pa->leftchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
Last函数(获取该树在中序遍历中的最后一个元素并返回):
BstNode* Last(BstNode* ptr)
{
while (ptr != NULL && ptr->rightchild != NULL)
{
ptr = ptr->rightchild;
}
return ptr;
}
非递归中序遍历:
void NiceInOrder(BsTree* ptree)
{
for (BstNode* ptr = First(ptree->root); ptr != NULL; ptr = Next(ptr))
{
cout << " " << ptr->key;
}
cout << endl << endl;
}
运行结果:
测试主函数:
int main()
{
BsTree tree = { 0 };
int ar[] = { 53,17,78,9,45,65,87,23,81,94,88,17 };
InitTree(&tree);
int n = sizeof(ar) / sizeof(ar[0]);
for (int i = 0; i < n; i++)
{
Insert_Item(&tree, ar[i]);
}
NiceInOrder(&tree);
return 0;
}
Prev函数(获取该节点在中序遍历中的上一个元素并返回):
BstNode* Prev(BstNode* ptr)
{
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 ResNiceInOrder(BsTree* ptree)
{
for (BstNode* ptr = Last(ptree->root); ptr != NULL; ptr = Prev(ptr))
{
cout << " " << ptr->key;
}
cout << endl << endl;
}
运行结果:
测试主函数:
int main()
{
BsTree tree = { 0 };
int ar[] = { 53,17,78,9,45,65,87,23,81,94,88,17 };
InitTree(&tree);
int n = sizeof(ar) / sizeof(ar[0]);
for (int i = 0; i < n; i++)
{
Insert_Item(&tree, ar[i]);
}
ResNiceInOrder(&tree);
return 0;
}
查寻元素:
BstNode* FindValue(BstNode* ptr, const int kx)
{
if (ptr != NULL && ptr->key == kx)
{
return ptr;
}
else if (ptr != NULL && ptr->key < kx)
{
return FindValue(ptr->rightchild, kx);
}
else if (ptr != NULL && ptr->key > kx)
{
return FindValue(ptr->leftchild, kx);
}
else
{
return NULL;
}
}
删除元素:
void Remove_Item(BsTree* ptree, const int kx)
{
if (ptree->root == NULL)
{
return;
}
BstNode* ptr = FindValue(ptree->root, kx);
if (ptr == NULL)
{
cout << "无此元素" << endl;
return;
}
if (ptr->leftchild != NULL && ptr->rightchild != NULL)
{
BstNode* nextnode = Next(ptr);
ptr->key = nextnode->key;
ptr = nextnode;
}
BstNode* pa = ptr->parent;
BstNode* child = ptr->leftchild != NULL ? ptr->leftchild : ptr->rightchild;
if (child != NULL)
{
child->parent = pa;
}
if (pa != NULL)
{
if (pa->leftchild == ptr)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
else
{
ptree->root = child;
}
free(ptr);
ptree->cursize -= 1;
}
运行结果:
测试主函数:
int main()
{
BsTree tree = { 0 };
int ar[] = { 53,17,78,9,45,65,87,23,81,94,88,17 };
InitTree(&tree);
int n = sizeof(ar) / sizeof(ar[0]);
for (int i = 0; i < n; i++)
{
Insert_Item(&tree, ar[i]);
}
int kx;
while (cin >> kx && kx != -1)
{
Remove_Item(&tree, kx);
NiceInOrder(&tree);
}
return 0;
}