一.BST树
1.定义:
BST树又称为二叉搜索树或二叉排序树。或者是空树,或者具有以下的性质:
- 每个结点都有作为搜索依据的关键码(key),所有结点的关键码互不相同。
- 左子树上所有节点的关键码都小于根节点。
- 右子树上所有结点的关键码都大于根节点。
- 左子树和右子树也都是二叉搜索树。
- 对其进行中序排序,值从小到大。
二叉树的结构如下图所示:
cursize代表这棵树一共有多少个结点(不包含头结点)
头结点是53上面的这个结点,根节点是关键码为53的这个节点。
设计头结点的原因:头结点作为迭代器的终止条件。
头结点里面的值是一个随机值,左孩子指向左子树的最小值,右孩子指向右子树的最大值,双亲指向头结点。
2.结构设计
typedef struct BstNode //对于结点的结构体
{
struct BstNode *leftchild;
struct BstNode *parent;
struct BstNode *rightchild;
KeyType key;
}BstNode;
typedef struct //
{
BstNode *head;
int cursize;
}BSTree;
3.查询val值
-
非递归查询
struct BstNode* FindValue(BSTree *mytree,int kx)
{
if(mytree == NULL) return NULL;
struct BstNode *p = mytree->head->parent;//root
while(p != NULL && p->key != kx)
{
p = kx < p->key?p->leftchild:p->rightchild;
}
return p;
}
-
递归查询
struct BstNode *Search(BstNode *node,int kx)
{
if(NULL == node || node->key == kx)
return node;
else if(node < kx)
return Search(node->rightchild,kx)
else
return Search(node->leftchild,kx);
}
struct BstNode *SearchValue(BSTree *myterr,int kx)//判断头结点是否成功
{
struct BstNode *p = NULL;
if(mytree != NULL)
{
p = SearchValue(mytree->head->parent,kx);
}
return p;
}
4.中序遍历
-
不使用栈,进行非递归遍历
通过观察二叉排序树,当结点在根结点的左边时,结点的双亲时结点的直接后继。
先找到这棵树的中序遍历的第一个结点,如果该结点是双亲结点的左孩子,那么双亲结点是该结点的直接后继;否则,如果该结点是双亲结点的右孩子,则要向上找。
struct BstNode *First(struct BstNode *ptr)//寻找第一个结点
{
while(ptr != NULL && ptr->leftchild != NULL)
{
ptr = ptr->leftchild;
}
return ptr;
}
struct BstNode *Next(BSTree *ptree,struct BstNode *ptr)//寻找第一个结点的后序结点
{
if(ptr == NULL)
return NULL;
if(ptr->rightchild != NULL)
{
return First(ptr->rightchild);//寻找ptr右孩子的第一个最小结点
}
else
{
struct BstNode *pa = ptr->parent;
while(pa != ptree->head && ptr != pa->leftchild)
{
ptr = pa;
pa = ptr->parent;
}
if(pa == ptree->head)
{
pa = NULL;
}
return pa;
}
}
void NiceInOrder(BSTree *ptree)
{
assert(ptree != NULL);
for(struct BstNode *p = First(ptree->head->parent);p!=NULL;p=Next(ptree,p))
{
cout<<p->key<<" ";
}
cout<<endl;
}
-
非递归中序倒序遍历
方法根非递归中序遍历一样
BstNode *Last(BstNode *ptr)
{
while(ptr != NULL && ptr->rightchild != NULL)
{
ptr = ptr->rightchild;
}
return ptr;
}
BstNode *Pre(BSTree *ptree,BstNode *ptr)
{
if(ptr == NULL)
return NULL;
if(ptr->leftchild != NULL)
{
return Last(ptr->leftchild);
}
else
{
struct BstNode *pa = ptr->parent;
while(pa != ptree->head && ptr != pa->rightchild)
{
ptr = pa;
pa = ptr->parent;
}
while(pa == ptree-