定义:二叉搜索树,又称二叉排序树。顾名思义,它是一种树形结构,并且根据名字可以体现出它有排序和搜索两个特征。
- 排序。对一个二叉排序树进行中序遍历,得到的是有序的序列。
- 搜索。在二叉排序树中对最大元素和最小元素进行搜索会十分遍历。最小元素在树的最左边,最大元素在树的最右边
对于二叉排序树主要有以下操作:
- 购买节点
- 释放节点
- 初始化树
- 插入元素
- 查找结点(非递归)
- 查找结点(递归)
- 中序遍历(递归)
- 中序遍历(非递归)
- 寻找以某个结点为根,其最左边的节点
- 寻找后继节点
- 寻找前驱结点
- 删除节点
首先我们先定义一下二叉排序树所需要的数据结构。
typedef int KeyType;
//树的节点类型
typedef struct BstNode
{
BstNode *leftchild;
BstNode *parent;
BstNode *rightchild;
KeyType data;
}BstNode;
//二叉排序树的头节点
typedef struct
{
BstNode *head;//根节点;
int cursize;//表示树中的节点个数
}BSTree;
1、购买节点
/*
第一个参数:父亲节点
第二个参数:左孩子
第三个参数:右孩子
*/
BstNode * Buynode(BstNode *pa = NULL,BstNode *left=NULL,BstNode *right = NULL)
{
BstNode *s = (BstNode*)malloc(sizeof(BstNode));
if(NULL == s) exit(1);
s->leftchild = left;
s->parent = pa;
s->rightchild = right;
return s;
}
2、释放节点
void Freenode(BstNode *p)
{
free(p);
}
3、初始化二叉排序树
void InitBSTree(BSTree &bt)
{
bt.head = Buynode();
bt.cursize = 0;
}
4、插入元素
bool InsertItem(BSTree &bt,KeyType kx)
{
BstNode *pa = bt.head; // head
BstNode *p = bt.head->parent; // root;
while(p != NULL && p->data != kx)
{
pa = p;
p = kx < p->data? p->leftchild:p->rightchild;
}
if(p != NULL) return false;
p = Buynode(pa);
p->data = kx;
if(pa == bt.head)
{
bt.head->parent = p;
bt.head->leftchild = p;
bt.head->rightchild = p;
}
else
{
if(p->data < pa->data)
{
pa->leftchild = p;
if(p->data < bt.head->leftchild->data)
{
bt.head->leftchild = p;
}
}
else
{
pa->rightchild = p;
if(p->data > bt.head->rightchild->data)
{
bt.head->rightchild = p;
}
}
}
bt.cursize+=1;
return true;
}
5、查找结点(非递归)
BstNode * FindValue(BSTree &bt,KeyType kx)
{
BstNode *p = bt.head->parent;
while(p != NULL && p->data != kx)
{
p = kx < p->data? p->leftchild:p->rightchild;
}
return p;
}
6、查找结点(递归)
BstNode * Search(BstNode *ptr,KeyType kx)
{
if(ptr == NULL || ptr->data == kx)
return ptr;
else if(kx < ptr->data)
return Search(ptr->leftchild,kx);
else
return Search(ptr->rightchild,kx);
}
BstNode * SearchValue(BSTree &bt,KeyType kx)
{
return Search(bt.head->parent,kx);
}
7、中序遍历(递归)
void InOrder(BstNode *p)
{
if(p != NULL)
{
InOrder(p->leftchild);
cout<<p->data<<" ";
InOrder(p->rightchild);
}
}
void InOrder(BSTree &bt)
{
InOrder(bt.head->parent);
cout<<endl;
}
8、中序遍历(非递归)
void NiceInOrder(BSTree &bt)
{
for(BstNode *p = First(bt.head->parent);
p != NULL; p = Next(bt,p) )
{
cout<<p->data<<" ";
}
cout<<endl;
}
9、寻找以某个结点为根,其最左边的节点
BstNode * First(BstNode *ptr)
{
while(ptr != NULL && ptr->leftchild != NULL)
{
ptr = ptr->leftchild;
}
return ptr;
}
10、寻找后继结点
BstNode * Next(BSTree &bt,BstNode *ptr)
{
if(ptr == NULL || ptr == bt.head) return NULL;
if(ptr->rightchild != NULL)
{
return First(ptr->rightchild);
}
else
{
BstNode *pa = ptr->parent;
while(pa != bt.head && pa->leftchild != ptr)
{
ptr = pa;
pa = pa->parent;
}
if(pa == bt.head)
{
pa = NULL;
}
return pa;
}
}
11、寻找前驱结点
BstNode * Pre(BSTree &bt, BstNode *ptr)
{
if (ptr == NULL || ptr == bt.head) return NULL;
BstNode *p = bt.head->parent;
while (p != NULL && Next(bt, p) != ptr)
{
p = Next(bt, p);
}
return p;
}
12、删除结点
bool RemoveItem(BSTree &bt,KeyType kx)
{
if(Empty(bt)) return false;
BstNode *p = FindValue(bt,kx);
if(NULL == p) return false;
if(p->leftchild != NULL && p->rightchild != NULL)
{
BstNode *nt = Next(bt,p);
p->data = nt->data;
p = nt;
}// leaf brch
BstNode *pa = p->parent;
BstNode *child = p->leftchild != NULL? p->leftchild: p->rightchild;
if(child != NULL) child->parent = pa;
if(pa == bt.head)
{
bt.head->parent = child;
}
else
{
if(pa->leftchild == p)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
Freenode(p);
bt.cursize-=1;
return true;
}