二叉查找树(英语: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){
- //若二叉查找树T中存在关键字等于key的数据元素时,则删除该数据元素,并返回
- //TRUE;否则返回FALSE
- if(!T)
- return false; //不存在关键字等于key的数据元素
- else{
- if(key == T->data.key) { // 找到关键字等于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; //s指向被删结点的“前驱”
- if(q!=p)
- q->rchild = s->lchild; //重接*q的右子树
- else
- q->lchild = s->lchild; //重接*q的左子树
- delete s;
- }
- return true;
- }
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29876893/viewspace-1988155/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29876893/viewspace-1988155/