二叉查找树(Binary Search Tree缩写:BST):也称二叉排序树,特征:1)如果左子树不为空,左子树的值小于对应的父节点;2)如果右子树不为空,右子树大于对应的父节点;也就是左<中<右;
插入操作:类似二叉链表,就是在二叉链表的基础上加上判断条件
typedef int dataType;
typedef struct Node
{
dataType data;
struct Node *rChild;
struct Node *lChild;
}BSTNode,*pBST;
//插入节点(pos为根结点指针)
void insertNode(pBST *pos,dataType data)
{
pBST root = NULL;
if(*pos == NULL)
{
root = (pBST)malloc(sizeof(BSTNode));
root->data = data;
root->rChild = NULL;
root->lChild = NULL;
*pos = root;
}
else if((*pos)->data<data)
{
insertNode(&((*pos)->rChild),data);
}
else if((*pos)->data>data)
{
insertNode(&((*pos)->lChild),data);
}
}
删除操作: 删除操作分为三种情况:1)待删节点为叶子节点;2)待删节点只有左子树或右子树;3)待删节点有左右子树
对于1):直接删除
对于2):用待删结点的子节点替换
对于3)需要找到待删结点的前驱或者后继节点替换(前驱和后继节点是在中序遍历的基础上说的:中序遍历正好为升序)
对于删除,分别判断使用前驱节点或后继节点替换的情况
typedef int dataType;
typedef struct Node
{
dataType data;
struct Node *rChild;
struct Node *lChild;
}BSTNode,*pBST;
//删除节点
BSTNode * deleteNode(pBST root,dataType data)
{
BSTNode *pos,*son,*father,*front; //pos:删除的目标节点;son:pos子节点(替换pos);father:pos父节点;front:son的前驱节点
pos = root;
father = NULL;
while(pos)
{
if(pos->data == data) break;
father = pos;
if(pos->data>data)
{
pos = pos->lChild;
}
else
{
pos = pos->rChild;
}
}
if(pos == NULL)
{
return root;
}
//使用后继节点替换(后继节点在右子树的最左下角)
if(pos->lChild == NULL)
{
//pos为根节点
if(father==NULL)
{
root = pos->rChild;
}
else if(father->lChild == pos)
{
father->lChild = pos->rChild;
}
else
{
father->rChild = pos->rChild;
}
free(pos);
}
//使用前驱节点替换(前驱节点在左子树的最右下角)
else
{
front = pos;
son = front->lChild;
while(son->rChild)
{
front = son;
son = son->rChild;
}
if(pos == front)
{
front->lChild = son->lChild;
}
else
{
front->rChild = son->lChild;
}
pos->data = son->data;
free(son);
}
return root;
}
测试程序:
#include <iostream>
using namespace std;
typedef int dataType;
typedef struct Node
{
dataType data;
struct Node *rChild;
struct Node *lChild;
}BSTNode,*pBST;
//插入节点(pos为根结点指针)
void insertNode(pBST *pos,dataType data)
{
pBST root = NULL;
if(*pos == NULL)
{
root = (pBST)malloc(sizeof(BSTNode));
root->data = data;
root->rChild = NULL;
root->lChild = NULL;
*pos = root;
}
else if((*pos)->data<data)
{
insertNode(&((*pos)->rChild),data);
}
else if((*pos)->data>data)
{
insertNode(&((*pos)->lChild),data);
}
}
//建立二叉搜索树
void createBST(pBST *root)
{
dataType data;
*root = NULL;
cin>>data;
while(data != -1)
{
insertNode(root,data);
cin>>data;
}
}
void print(pBST root)
{
if(root)
{
print(root->lChild);
cout<<root->data<<" ";
print(root->rChild);
}
}
//删除节点
BSTNode * deleteNode(pBST root,dataType data)
{
BSTNode *pos,*son,*father,*front; //pos:删除的目标节点;son:pos子节点(替换pos);father:pos父节点;front:son的前驱节点
pos = root;
father = NULL;
while(pos)
{
if(pos->data == data) break;
father = pos;
if(pos->data>data)
{
pos = pos->lChild;
}
else
{
pos = pos->rChild;
}
}
if(pos == NULL)
{
return root;
}
if(pos->lChild == NULL)
{
//pos为跟节点
if(father==NULL)
{
root = pos->rChild;
}
else if(father->lChild == pos)
{
father->lChild = pos->rChild;
}
else
{
father->rChild = pos->rChild;
}
free(pos);
}
else
{
front = pos;
son = front->lChild;
while(son->rChild)
{
front = son;
son = son->rChild;
}
if(pos == front)
{
front->lChild = son->lChild;
}
else
{
front->rChild = son->lChild;
}
pos->data = son->data;
free(son);
}
return root;
}
BSTNode * findNode(BSTNode * root,dataType data)
{
BSTNode * pos;
pos= root;
while(pos)
{
if(pos->data == data) return pos;
else if(pos->data > data) pos = pos->lChild;
else pos= pos->rChild;
}
return NULL;
}
int main() {
pBST root;
cout<<"create BST,please input data:"<<endl;
createBST(&root);
print(root);
cout<<"delete node:"<<endl;
dataType n;
// cin>>n;
// deleteNode(root,n);
// print(root);
cout<<"findNode:"<<endl;
cin>>n;
cout<<findNode(root,n)->data<<endl;
return 0;
}