二叉树的一个重要应用是二叉查找树。假设树中每个节点被指定一个关键字值。使二叉树成为二叉查找树的性质是,对于树中的每个节点X,它的左子树中所有元素值小于X的值,而右子树中所有元素值大于X的值。这意味着,该树所有的元素可以用某种统一方式排序。如下图,左边是二叉查找树,但右边则不是(值为7的节点不符合要求)。
下面我们对二叉查找树的操作简要描述。由于树的递归定义,通常是递归地编写这些操作的例程。因为二叉查找树的平均深度是O(log N),所以一般不必担心栈空间被用尽。
首先,声明二叉查找树的数据结构和一些常见的操作函数。
#include <Tree.h>
//创建一个二叉查找树
#ifndef _Tree_H_
#define _Tree_H_
struct TreeNode{
int element; //节点存储信息可以根据需要修改!
TreeNode* Left;
TreeNode* Right;
};
void MakeEmpty(TreeNode* T);
TreeNode* Find(int X, TreeNode* T);
TreeNode* FindMin(TreeNode* T);
TreeNode* FindMax(TreeNode* T);
TreeNode* Insert(int X, TreeNode* T);
TreeNode* Delete(int X, TreeNode* T);
#endif
下面,我们用高度递归的方法(大大减少代码量)分别实现这些操作。
#include <Tree.cpp>
#include "tree.h"
#include <stdlib.h>
#include <iostream>
void MakeEmpty(TreeNode* T)
{
if(T)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
delete T;
}
}
TreeNode* Find(int X, TreeNode* T)
{
if(!T)
return NULL;
else if(X < T->element)
return Find(X,T->Left);
else if(X > T->element)
return Find(X,T->Right);
else
return T;
}
TreeNode* FindMin(TreeNode* T) //这个用递归法
{
if(!T)
return NULL;
else if(T->Left)
return FindMin(T->Left);
else
return T;
}
TreeNode* FindMax(TreeNode* T) //这个不用递归
{
if(T)
while(T->Right)
T = T->Right;
return T;
}
TreeNode* Insert(int X, TreeNode* T)
{
if(!T) //这个条件的判定一定要放在第一位!
{
T = new TreeNode;
T->element = X;
T->Left = T->Right = NULL;
}
else if(X < T->element)
{
T->Left = Insert(X, T->Left);
}
else if(X > T->element)
{
T->Right = Insert(X, T->Right);
}
else
; //如果X==T->element,表示X本来就在Tree中,什么也不需要做!
return T;
}
TreeNode* Delete(int X, TreeNode* T)
{
TreeNode* temp;
if(!T)
std::cout<<"没找到要删除的节点!";
else if(X < T->element)
T->Left = Delete(X, T->Left);
else if(X > T->element)
T->Right = Delete(X, T->Right);
else if(T->Left && T->Right) //被删除节点有两个儿子
{
//用右子树中最小的节点来顶替被删除的节点
//这种方法会造成二叉树整体向左倾斜
temp = FindMin(T->Right);
T->element = temp->element;
T->Right = Delete(temp->element,T->Right); //继续递归
}
else //被删除节点有0或1个儿子
{
temp = T;
if(!T->Left)
T = T->Right;
else
T = T->Left;
delete temp;
}
return T;
}