二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
-
任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
-
若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
-
任意节点的左、右子树也分别为二叉查找树;
-
没有键值相等的节点。
从上述定义可知,二叉排序树是记录之间满足一定次序关系的二叉树。下面介绍如何构建一棵二叉排序树,以及遍历,插入,查找,也会简单的介绍删除结点操作。
构造一棵排序二叉树,则一定要根据其定义来实现。下面给出相关代码:
-
#include<iostream>
-
using namespace std;
-
typedef struct bstNote {
-
int data;
-
struct bstNote *lchild, *rchild;
-
}*bstTree;
-
-
void insertNote(bstTree &bst, int _data) {
-
if (bst == NULL) {
-
bst = new bstNote;
-
bst->data = _data;
-
bst->lchild = bst->rchild = NULL;
-
return;
-
}
-
if (bst->data == _data) {
-
exit(-1);
-
}
-
-
else if(bst->data > _data)
-
insertNote(bst->lchild, _data);
-
-
else
-
insertNote(bst->rchild, _data);
-
}
-
void createBST(bstTree &bst,int *arry,int length){
-
bst = NULL;
-
-
for (int i = 0; i < length; i++) {
-
insertNote(bst, arry[i]);
-
}
-
}
-
void preOrder(bstTree bst) {
-
if (bst == NULL) {
-
return;
-
}
-
-
cout << bst->data << " ";
-
preOrder(bst->lchild);
-
preOrder(bst->rchild);
-
-
}
-
void inOrder(bstTree bst) {
-
if (bst == NULL) {
-
return;
-
}
-
inOrder(bst->lchild);
-
cout << bst->data << " ";
-
inOrder(bst->rchild);
-
}
-
void postOrder(bstTree bst) {
-
if (bst == NULL) {
-
return;
-
}
-
postOrder(bst->lchild);
-
postOrder(bst->rchild);
-
cout << bst->data << " ";
-
}
-
bstTree searchBST(bstTree bst, int key) {
-
if (bst == NULL)
-
return false;
-
else if (bst->data == key) {
-
cout << "查找成功:"<<bst->data<< endl;
-
return bst;
-
}
-
else if(bst->data>key)
-
return searchBST(bst->lchild, key);
-
else
-
return searchBST(bst->rchild, key);
-
}
-
int main(){
-
bstTree bst;
-
int arry[] = {4,5,2,1,3,10,7,8,6,0};
-
int length = sizeof(arry) / sizeof(int);
-
createBST(bst, arry, length);
-
cout << "PreOrder:" << endl;;
-
preOrder(bst);
-
cout << endl;
-
cout << "InOrder:" << endl;
-
inOrder(bst);
-
cout << endl;
-
cout << "PostOrder:" << endl;;
-
postOrder(bst);
-
cout << endl;
-
searchBST(bst,6);
-
insertNote(bst, 9);
-
preOrder(bst);
-
cout << endl;
-
inOrder(bst);
-
}
上面的代码比较简单的实现构造,遍历,查找。
但是在二叉查找树删去一个结点,分三种情况讨论:(如下参考维基百科:点击打开链接)
1.若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。
2.若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉查找树的特性。
3.若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:其一是令*p的左子树为*f的左/右(依*p是*f的左子树还是右子树而定)子树,*s为*p左子树的最右下的结点,而*p的右子树为*s的右子树;其二是令*p的直接前驱(in-order predecessor)或直接后继(in-order successor)替代*p,然后再从二叉查找树中删去它的直接前驱(或直接后继),该种情况较为复杂,如下图示。

算法:
-
Status DeleteBST(BiTree &T, KeyType key){
-
-
-
if(!T)
-
return false;
-
else{
-
if(key == T->data.key) {
-
return Delete(T);
-
}
-
else if(key < T->data.key)
-
return DeleteBST(T->lchild, key);
-
else
-
return DeleteBST(T->rchild, key);
-
}
-
}
-
Status Delete(BiTree &p){
-
-
BiTree *q, *s;
-
if (!p->rchild && !p->lchild)
-
{
-
delete p;
-
p = NULL;
-
}
-
else if(!p->rchild){
-
q=p->lchild;
-
p->data = p->lchild->data;
-
p->lchild=p->lchild->lchild;
-
p->rchild=p->lchild->rchild;
-
-
delete q;
-
}
-
else if(!p->lchild){
-
q=p->rchild;
-
p->data = p->rchild->data;
-
p->lchild=p->rchild->lchild;
-
p->rchild=p->rchild->rchild;
-
-
delete q; }
-
else{
-
q=p;
-
s=p->lchild;
-
while(s->rchild){
-
q=s;
-
s=s->rchild;
-
}
-
p->data = s->data;
-
if(q!=p)
-
q->rchild = s->lchild;
-
else
-
q->lchild = s->lchild;
-
delete s;
-
}
-
return true;
-
}
-
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29876893/viewspace-1988155/
,如需转载,请注明出处,否则将追究法律责任。