版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YL970302/article/details/86567283
BST树:(也称二叉排序树或二叉搜索树)
特点:如果左孩子不空,则左孩子一定比根结点值要小,如果右孩子不空,则右孩子一定比根节点值要大
头结点的组成如下:
Lchild(指向BST最小结点) | parent(指向BST的根) | data(随机值) | Rchild(指向BST最大结点) |
一、创建结点:
#include<iostream>
using namespace std;
typedef int ElemType;
typedef struct BstNode
{
BstNode *LeftChild;
BstNode *parent;
BstNode *RightChild;
ElemType data;
}BstNode;
typedef struct
{
BstNode *head;
int Cursize ;
}BSTree;
二、购买结点和释放结点
BstNode *BuyNode(BstNode *parent = NULL, BstNode *Leftchild = NULL, BstNode *Rightchild = NULL)
{
BstNode *p = (BstNode *)malloc(sizeof(BstNode));
if(NULL == p)
{
return NULL;
}
p->LeftChild = Leftchild;
p->parent = parent;
p->RightChild = Rightchild;
return p;
}
void FreeNode(BstNode *p)
{
free(p);
}
三、初始化:
void InitBSTree(BSTree &bt)
{
bt.Cursize = 0;
bt.head = BuyNode();
}
四、非递归查找某个数值的结点
BstNode *FindValue(BSTree &bt, ElemType x) //非递归查找
{
BstNode *p = bt.head->parent;
while (p!= NULL && p->data != x)
{
p = x > p->data ? p->RightChild:p->LeftChild;
}
if(p->data == x)
return p;
}
五、递归查找某个数值的结点
BstNode *Search(BstNode *p,ElemType x)
{
if(p == NULL || p->data == x)
return p;
else if(p->data > x)
{
return Search(p->LeftChild,x);
}
else
{
return Search(p->RightChild,x);
}
}
BstNode *SearchValue(BSTree &bt, ElemType x) //递归查找
{
return Search(bt.head->parent,x);
}
六、插入结点
bool InsertItem(BSTree &bt, ElemType x)
{
BstNode *pa = bt.head; //head
BstNode *p = bt.head->parent; //root
while (p!= NULL && p->data != x)
{
pa = p;
p = x > p->data ? p->RightChild:p->LeftChild;
}
if(p != NULL)
{
return false;
}
p = BuyNode(pa);
p->data = x;
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(bt.head->LeftChild->data > p->data) //维护BST树中,头结点左指针指向树中最小值结点
{
bt.head->LeftChild = p;
}
}
else
{
pa->RightChild = p;
if(bt.head->RightChild->data < p->data)//维护BST中,头结点右孩子指向树中最大值得结点
{
bt.head->RightChild = p;
}
}
}
bt.Cursize += 1;
return true;
}
七、非递归中序遍历
BstNode *First(BstNode *ptr)
{
while(ptr != NULL && ptr->LeftChild != NULL)
{
ptr = ptr->LeftChild;
}
return ptr;
}
BstNode * Next(BSTree &bt,BstNode *ptr)
{
if(NULL == ptr || 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;
}
}
//非递归遍历
void NiceInOrder(BSTree &bt)
{
for(BstNode *p = First(bt.head->parent); p != NULL ; p = Next(bt,p))
{
cout<<p->data<<" ";
}
cout<<endl;
}
八、递归中序遍历
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;
}
九、删除结点:
在删除结点的时候要考虑:
(1)空树
(2)是否找得到要删除的结点
(3)叶子结点
(4)单分支
(5)双分支双分支转换为删除它的找它的直接前驱或者直接后继删除,然后进行替换
int GetSize(BSTree &bt)
{
return bt.Cursize;
}
bool Empty(BSTree &bt)
{
return GetSize(bt) == 0;
}
bool RemoveItem(BSTree &bt, ElemType x)//删除某一结点
{
if(Empty(bt)) //二叉树是否为空
{
return false;
}
BstNode *p = FindValue(bt,x); //能否找得到要删除的结点
if(NULL == p)
{
return false;
}
if(p->LeftChild != NULL && p->RightChild != NULL) //删除的是有双分支的结点
{
BstNode *nt = Next(bt,p);
p->data = nt->data;
p = nt;
}
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;
}
十、测试
int main()
{
int ar[]={53,17,78,9,45,65,87,23,81,94,88};
int n = sizeof(ar)/sizeof(ar[0]);
int x = 0;
BSTree myt;
InitBSTree(myt);
for(int i = 0;i<n;++i)
{
InsertItem(myt,ar[i]);
}
NiceInOrder(myt);
ResNiceInOrder(myt);
while(cin>>x , x != -1)
{
RemoveItem(myt,x);
NiceInOrder(myt);
}
cout<<"InsertItem(myt,16) "<<InsertItem(myt,16)<<endl;
NiceInOrder(myt);
BstNode *p1 = FindValue(myt,23);
cout<<"FindValue(myt,23) "<<p1->data<<endl;
BstNode *p2 = SearchValue(myt,23);
cout<<"SearchValue(myt,23) "<<p2->data<<endl;
return 0;
}
十一、结果展示: