一、二叉搜索树的概念:
1.二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
(1)若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
(2)若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
(3)它的左右子树也分别为二叉搜索树
给定值的比较次数等于给定值节点在二叉排序树中的层数。如果二叉排序树是平衡的,则n个节点的二叉排序树的高度为Log2n+1,其查找效率为O(Log2n),近似于折半查找。如果二叉排序树完全不平衡,则其深度可达到n,查找效率为O(n),退化为顺序查找。一般的,二叉排序树的查找性能在O(Log2n)到O(n)之间。因此,为了获得较好的查找性能,就要构造一棵平衡的二叉排序树。
二、二叉搜索树的基本操作:
1.查找
(1)如果 key == root->key ,表示已找到;
(2)如果 key < root->key,去左子树中找;
(3)如果 key > root->key,去右子树中找;
2.插入
(1)进行查找,如果找到,插入失败;
(2)如果root == NULL,在这个位置插入 key,需要修改双亲节点的 left 或者 right;
(3)如果对空树做插入需要特殊处理;
3.删除
若找到:
(1)三种 cur->left == NULL情况;
(2)三种 cur->right == NULL情况;
(3)左右子树均不为空,这里选右子树替换删除;
若未找到:
则删除失败。
BSTreeNode.h
#pragma once
#include <stidio.h>
#include <stdlib.h>
#include <assert.h>
typedef int Key;
typedef struct BSTreeNode
{
struct BSTreeNode *left;
struct BSTreeNode *right;
int key;
}BSTreeNode;
int BSTreeSearch(BSTreeNode *root,Key key);
//递归实现查找
int BSTreeSearchNor(BSTreeNode *root,Key key);
//非递归实现查找
int BSTreeInsert(BSTreeNode *root,Key key);
//递归实现插入
int BSTreeInsertNor(BSTreeNode *root,Key key);
//非递归实现插入
int BSTreeRemove(BSTreeNode *root,Key key);
//非递归实现删除
BSTreeSearch.c
int BSTreeSearch(BSTreeNode *root,Key key)
{
assert(root);
if(NULL == root)
{
return -1;
}
if(key == root->key)
{
return 0;
}
if(key<root->key)
{
return BSTreeSearch(root->left,key);
}
return BSTreeSearch(root->right,key);
}
int BSTreeSearchNor(BSTreeNode *root,Key key)
{
assert(root);
BSTreeNode *cur = root;
if(NULL == root)
{
return -1;
}
while(cur)
{
if(key == cur->key)
{
return 0;
}
if(key<cur->key)
{
cur = cur->left;
}
if(key>cur->key)
{
cur = cur->right;
}
}
return -1;
}
int BSTreeInsert(BSTreeNode **root,Key key)
{
assert(root);
if(NULL == *root)
{
BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
node->key = key;
node->left = NULL;
node->right = NULL;
*root = node;
}
if(key == (*root)->key)
{
return -1;
}
if(key<(*root)->key)
{
return BSTreeInsert(&(*root)->left,key);
}
else
{
return BSTreeInsert(&(*root)->right,key);
}
}
int BSTreeInsertNor(BSTreeNode **root,Key key)
{
assert(root);
BSTreeNode *cur = *root;
BSTreeNode *parent = NULL;
while(cur)
{
if(key == cur->key)
{
return -1;
}
parent = cur;
if(key<cur->key)
{
cur = cur->left;
}
else
{
cur = cur->right;
}
}
BSTreeNode *node = (BSTreeNode*)malloc(sizeof(BSTreeNode));
node->key = key;
node->left = NULL;
node->right = NULL;
if(parent == NULL)
{
*root = node;
}
else if(key<parent->key)
{
parent->left = node;
}
else
{
parent->right = node;
}
return 0;
}
int BSTreeRemove(BSTreeNode **root, Key key)
{
assert(root);
BSTreeNode *cur = *root;
BSTreeNode *parent = NULL;
while (cur)
{
if (cur->key == key)
{
//左孩子为空的三种情况
if (NULL == cur->left)
{
if (NULL == parent)
{
*root = cur->right;
}
else if (key<parent->key)
{
parent->left = cur->right;
}
else
{
parent->right = cur->right;
}
}
//右孩子为空的三种情况
if (NULL == cur->right)
{
if (NULL == parent)
{
*root = cur->left;
}
else if (key<parent->key)
{
parent->left = cur->left;
}
else
{
parent->right = cur->left;
}
}
else
{
//左右孩子均不为空
//找右子树中最小来替换删除
BSTreeNode *del = cur->right;
BSTreeNode *delparent = cur;
while (del->left)
{
delparent = del;
del = del->left;
}
cur->key = del->key;
if (delparent == cur)
{
delparent->right = del->right;
}
else
{
delparent->left = del->right;
}
}
}
parent = cur;
if (key<cur->key)
{
cur = cur->left;
}
else
{
cur = cur->right;
}
}
return -1;
}