二叉搜索树的建立
二叉搜索树的建立即为向二叉树中插入元素.开始插入第一个元素时,二叉搜索树是空树,直接申请一个内存空间将元素放入树中.再插入元素时,从根节点开始比较,若待插入的元素值较大,则树中节点向右走,若较小,则树中节点向左走,直到找到一个空位置,将节点插入.
二叉搜索树中查找元素
在二叉搜索树中查找元素时,先将元素与根节点值比较,若元素的值较小,则根节点向左走(root = root->left);若元素值较大,则根节点向右走直到找到相等大小的元素或者走到树的尽头.
二叉搜索树的删除
若树为空,则直接返回FALSE; 树不空,若待删除元素大于节点元素,则递归查找该节点的右子树;若待删除元素小于节点元素,则递归查找该节点的左子树;若待删除元素等于节点元素,则继续判断. (a)如果该节点是叶子节点,则直接将该节点置为空; (b)如果该节点只有左孩子,则把它的左孩子赋给该节点; (c)如果该节点只有右孩子,则把它的右孩子赋给该节点; (d)如果该节点(令该节点为p)既有左孩子又有右孩子,则找到该节点的右孩子的最左端的左孩子(令该节点为s),将这个节点的右孩子(s->right)赋给这个节点(s)的父节点(parent)的左孩子(parent->left = s->right),把待删除的节点(p)的左孩子(p->left)赋给该节点(s)的左孩子(s->left = p->left),把待删除的节点(p)的右孩子(p->right)赋给该节点(s)的右孩子(s->right = p->right).给函数中传来的节点赋值s.将p节点释放.
二叉搜索树的遍历
二叉搜索树作为树,也可以对其进行先序,中序,后序遍历,且其中序遍历相当于对树中元素从大到小的有序输出.
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <malloc.h>
using namespace std;
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct STnode* link;
struct STnode{
int item;//元素值
link l;//该节点的左子树链接
link r;//该节点的右子树链接
};
//二叉搜索树的插入
link STinsert(link st, int num)
{
if(st == NULL)
{
//申请内存空间
link st = (link)malloc(sizeof(struct STnode));
//为节点赋值
st->item = num;
//将左右子树置为空
st->l = NULL;
st->r = NULL;
//将节点返回
return st;
}
//printf("*%d* ", st->item);
//该节点的值大于元素值的情况
if(st->item > num)
{
//递归调用节点的左子树
st->l = STinsert(st->l, num);
}
//该节点的值小于元素值的情况
else if(st->item < num)
{
//递归调用节点的右子树
st->r = STinsert(st->r, num);
}
}
//二叉搜索树中元素的查找
Status STsearch(link h,int v)
{
//空树,没有对应的值,查找失败
if(h == NULL)
{
return FALSE;
}
//找到对应的元素值,查找成功
if(v == h->item)
{
return TRUE;
}
//该节点的值大于元素值的情况
if(v < h->item)
{
//递归调用节点的左子树
STsearch(h->l, v);
}
//该节点的值小于元素值的情况
else
{
//递归调用节点的右子树
STsearch(h->r, v);
}
}
//删除节点代码
Status BSTdelete(link *st, int item)
{
link p = *st;
//空树的情况
if(!p)
{
return FALSE;
}
//找到了要删除的节点
if(p->item == item)
{
//如果该节点是叶子结点
if(!p->l && !p->r)
{
*st = NULL;
}
//如果该节点只有左孩子
else if(p->l && !p->r)
{
*st = p->l;
}
//如果该节点只有右孩子
else if(!p->l && p->r)
{
*st = p->r;
}
//如果该节点既有左孩子,又有右孩子
else
{
//将该节点的左孩子表示出来
link s = p->r;
//如果该节点的右孩子没有左孩子
if(!s->l)
{
s->l = p->l;
}
//如果该节点既有左孩子又有右孩子
else
{
//定义s节点的父节点parent
link parent = NULL;
//找到s节点下最左端的左叶子节点
while(s->l)
{
parent = s;
s = s->l;
}
//将s点断开
parent->l = s->r;
//将s点换到p点
s->l = p->l;
s->r = p->r;
}
//连成树
*st = s;
}
//将原节点释放掉
free(p);
return TRUE;
}
//如果元素值偏大
else if(item > ((*st)->item))
{
//递归右子树
BSTdelete(&(p->r), item);
}
//如果元素值偏小
else
{
//递归左子树
BSTdelete(&(p->l), item);
}
}
//递归树前序遍历
void Traverse1(link tree)
{
if(tree)
{
//先输出根结点
printf("%d ", tree->item);
//再递归其左子树
Traverse1(tree->l);
//再递归其右子树
Traverse1(tree->r);
}
}
//使用BST排序,即中序输出
void BSTsort(link h)
{
if(h == NULL)
{
return;
}
//递归调用左子树
BSTsort(h->l);
//输出元素值
printf("%d ", h->item);
//递归调用右子树
BSTsort(h->r);//递归调用
}
int main()
{
int a[12] = {2, 5, 3, 7, 6, 1, 4, 11, 8, 10, 9, 12};
link st = NULL;
int i;
//为空树中插入元素
for(i = 0; i < 12; i++)
{
st = STinsert(st, a[i]);
}
//先序遍历该二叉搜索树
Traverse1(st);
printf("\n");
//查找元素在二叉搜索树中是否存在
if(STsearch(st, 7))
{
printf("7 在树中存在.\n");
}
else
{
printf("** 在树中不存在.\n");
}
//中序遍历二叉搜索树,元素从小到大有序输出
BSTsort(st);
printf("\n");
//删除元素的情况
int flag = BSTdelete(&st, 11);
if(flag)
{
printf("删除成功!\n");
}
else
{
printf("要删除的元素不存在!\n");
}
//删除某个元素之后的先序遍历
Traverse1(st);
printf("\n");
//删除某个元素之后的中序遍历
BSTsort(st);
printf("\n");
return 0;
}