之前的博客中提到过,我学习采用的参考书是《数据结构与算法分析——C语言描述》。这门书的组织安排与国内广泛实用的教材《数据结构——C语言版》比较不同。这本书描述了一些树和二叉树的概念,举例讲解了什么是树的三种遍历之后,就开始重点讲解二叉查找树、平衡二叉树、AVL树、伸展树、B数了。这一篇博客,重点学习二叉查找树的概念和基本操作。
大家都知道,树的定义本身就带有递归性。因此,树的很多操作都涉及到了递归。
二叉查找树的定义如下:
1.二叉查找树首先是一棵二叉树;
2.二叉查找树除了是二叉树外,还具有以下性质:对于树中的任何一个节点X,其左子树中的所有节点的关键字均小于X的关键字的值;而其右子树中的所有关键字的值均大于X的关键字的值。下面两棵二叉树中,左边的二叉树是二叉查找树而右边的不是。
二叉查找树的数据结构定义如下:
typedef int ElementType;
typedef struct TreeNode *Position;
typedef Position BiSearchTree;
struct TreeNode
{
ElementType Element;
BiSearchTree Left,Right;
};
二叉查找树的常用操作如下:
BiSearchTree MakeEmpty(BiSearchTree Tree);
Position Find(ElementType X, BiSearchTree T);
Position FindMin(BiSearchTree T);
Position FindMax(BiSearchTree T);
BiSearchTree Insert(ElementType X,BiSearchTree T);
BiSearchTree Delete(ElementType X, BiSearchTree T);
二叉排序树的操作与之前学习的一些数据结构的操作相比,可能难理解一些。下面我们挑比较难的几个一一讲解。
1.二叉查找树中查找指定的元素Find
二叉排序树的性质是二叉排序树很多操作的基本依据。既然要查找指定元素X,先比较X与根节点元素的关系,如果刚好相等,直接返回啦;如果X小于根节点的元素值,那么去根节点的左子树中查找,也就是调用Find方法,只是传递的参数是X和根节点的左子树;如果X大于根节点的元素值,那么去根节点的右子树中查找,也就是调用Find函数,只是传递的参数是X和根节点的右子树。
2.查找最小元素FindMin和最大元素FindMax
这两个操作是类似的。采用迭代或者递归都可以实现,查找最小元素只需要沿着左子树访问下去,查找最大元素则相反。下面我们会分别采用递归和迭代实现这两个操作。
3.插入操作Insert
插入操作其实类似于查找操作,插入过过程其实就是先得找到一个合适的位置。插入其实有下面几个情况:
(1)如果函数传进来的是空树,那么创建一棵树,将其元素值设置为X。这种情况显而易见;
(2)如果不是空树,那就比较根节点元素值和X的大小,如果X的值小于根节点的元素值,而此时的根节点的左子树为空,那么根节点的左孩子就是X元素的归宿啦;同样的道理,如果X的值大于根节点的元素值,而此时根节点的右子树为空,那么根节点的右孩子就是X元素的归宿啦。把握住这一点其实基本上就能把握住这个操作了。文字描述可能比较抽象,下面看图:
左边的图,如果要插入5,沿着树一直找到节点4,这时5>4并且4的右孩子为空,那么5就是4的右孩子。右边的图,要想插入8,沿着树找到9,发现8<9且9的左孩子为空,那么8就是9的左孩子。
当然,在实现这样一个过程的时候可以使用递归。
4.删除操作Delete
删除操作是我认为最复杂最不好理解的一个操作。如果没有仔细想明白整个过程,上来就看代码的话可能会很晕。删除操作分两步:第一步是查找,找的过程就涉及元素值之间的比较。我们重点说找到之后的操作。假设我们找到了这个节点,现在要删除,涉及三种情况:
(1)该节点是叶子。这还有什么好说的,直接删了一了百了;
(2)该节点只有一个孩子节点。也不复杂,让该节点的父节点直接指向其子节点就行了。当然,也别忘了回收该节点;
(3)该节点有两个孩子:找到该节点右子树中最小的节点,将其元素值赋给该节点,然后删除那个最小节点。这种情况看图:
说了半天了,下面看看完整的代码:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct TreeNode *Position;
typedef Position BiSearchTree;
struct TreeNode
{
ElementType Element;
BiSearchTree Left,Right;
};
//建立一颗空树
BiSearchTree MakeEmpty(BiSearchTree Tree)
{
if(!Tree)
{
MakeEmpty(Tree->Left);
MakeEmpty(Tree->Right);
free(Tree);
}
return NULL;
}
//二叉查找树的Find操作
Position Find(ElementType X, BiSearchTree T)
{
if(T == NULL)
{
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;
}
}
}
//查找最小值:递归写法
Position FindMin(BiSearchTree T)
{
if(T == NULL)
{
return NULL;
}
else
{
if(T->Left == NULL)
{
return T;
}else
{
return FindMin(T->Left);
}
}
}
//查找最大值:非递归写法
Position FindMax(BiSearchTree T)
{
if(T->Right != NULL)
{
while(T->Right != NULL)
{
T = T->Right;
}
}
return T;
}
//插入元素X
BiSearchTree Insert(ElementType X,BiSearchTree T)
{
//当树为空树时
if(T == NULL)
{
T = malloc(sizeof(struct TreeNode));
if(T == NULL)
{
fprintf(stderr,"Out of Space!!!");
}
else
{
T->Element = X;
T->Left = NULL;
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
{
//do nothing!
}
}
return T;
}
//删除节点X
BiSearchTree Delete(ElementType X, BiSearchTree T)
{
Position TmpCell;
if(T==NULL)
{
fprintf(stderr,"Element does not exist!");
}
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)
{
TmpCell = FindMin(T->Right);
T->Element = TmpCell->Element;
T->Right = Delete(T->Element,T->Right);
}
else
{
TmpCell = T;
if(T->Left == NULL)
{
T = T->Right;
}
else if(T->Right == NULL)
{
T = T->Left;
}
free(TmpCell);
}
return T;
}
int main(void)
{
BiSearchTree T;
int index;
int arr[10] = {10,9,8,7,6,1,2,3,4,5};
T = NULL;
for(index=0; index < 10; index++)
{
T = Insert(arr[index],T);
}
T = Insert(18,T);
T = Insert(15,T);
printf("The minimum element is %d\n",FindMin(T)->Element);
printf("The maxmium element is %d\n",FindMax(T)->Element);
return 0;
}
分享到:
相关推荐
总结,"数据结构——二叉查找树(BST)静态查找表"的主题涵盖了如何使用数据结构实现BST,以及在静态查找表环境下BST的插入、删除、查找、遍历等操作及其效率。通过学习这部分内容,我们可以深入理解BST的原理,并能...
在这个“课程设计——二叉查找树”项目中,开发者创建了一个桌面应用程序,用于实现对二叉查找树的操作。用户可以通过界面进行交互,进行查找操作,同时能够直观地观察到操作的结果。这对于学习和理解二叉查找树的...
实验内容:建立有n个元素的二叉排序树,并在其上进行查找。 实验说明:(1)建立n个元素的二叉树,以链式结构存储,数据元素为整型。(2)在该二叉树上查找某数据,若查找成功则输出成功信息,若查找失败,则插入该数据...
### 数据结构课程设计——二叉排序树 #### 一、二叉排序树概念 二叉排序树(Binary Search Tree),也称作二叉查找树或有序二叉树,是一种特殊的二叉树数据结构。它具有以下性质: 1. 若任意节点的左子树不空,则左...
在数据结构的学习中,二叉排序树是一种非常重要的数据结构,它在许多实际应用中扮演着关键角色。在这个音像商店事务管理系统的设计中,我们可能会用到二叉排序树来高效地存储和检索音像制品的信息。下面我们将深入...
二叉查找树(Binary Search Tree,BST)是一种特殊的二叉树数据结构,它的每个节点都包含一个键(key)、一个关联的值、一个指向左子树的引用和一个指向右子树的引用。在二叉查找树中,对于任意节点,其左子树中的...
《数据结构》课程设计说明书——二叉排序树的判别 1. 问题描述与分析 二叉排序树(Binary Sort Tree,BST)是一种特殊的二叉树,其中每个节点的值都大于其左子树中的任何节点的值,且小于其右子树中的任何节点的值...
在这个课程设计报告中,我们将聚焦于一种特殊类型的二叉树——二叉平衡排序树,它在实际应用中展现出优秀的性能特点。 二叉平衡排序树,顾名思义,是一种保持平衡的二叉搜索树。传统的二叉搜索树在插入和删除操作后...
二叉查找树(Binary Search Tree,BST)是一种特殊的二叉树数据结构,它具有以下特性:对于树中的每个节点,其左子树上的所有节点的值都小于该节点的值,而右子树上的所有节点的值都大于该节点的值。这样的特性使得...
本实验——“数据结构二叉树实验——构造二叉搜索树”,旨在深入理解并实践二叉搜索树的构建过程和特性。 二叉搜索树是一种特殊的二叉树,每个节点都满足以下性质:左子树上的所有节点的键值小于父节点的键值;右子...
在计算机科学领域,二叉查找树(Binary Search Tree, BST)是一种非常重要的数据结构,它能够有效地实现查找、插入和删除等基本操作。然而,在某些情况下,普通的二叉查找树可能会退化成链式结构,导致性能下降。为了...
本实验专注于二叉查找树(Binary Search Tree, BST)以及它的平衡版本——AVL树。这两种数据结构在处理大量数据时,尤其是进行查找、插入和删除操作时,具有较高的效率。 首先,二叉查找树是一种特殊的二叉树,其中...
【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归) 在计算机科学中,数据结构是存储和组织数据的方式,它直接影响到数据的处理效率。搜索二叉树(BST,Binary Search Tree)是一种特殊类型的数据结构,...
在本实验“数据结构实验——查找算法的实现”中,主要关注的是数据结构中的查找算法,特别是二叉排序树和平衡二叉树的构建、查找、插入和删除操作。实验目的是通过实际操作来理解并比较不同查找算法的性能,如平均...
数据结构实验——查找子系统是IT领域中一项基础但至关重要的实践任务,它涉及到数据的组织、存储和访问策略。这个实验主要关注两种查找方法——顺序查找和二分查找,以及二叉排序树的相关操作,包括查找、插入、删除...
### 数据结构——二叉排序树算法 #### 1. 插入新节点 二叉排序树(Binary Search Tree, BST),也称为二叉查找树或者二叉搜索树,是一种特殊的二叉树,其中每个节点的左子树只包含键值小于该节点的节点;右子树只...
在本实验“数据结构实验——树和二叉树子系统”中,我们将深入理解二叉树的特性和操作。 首先,实验目的主要涵盖以下几个方面: 1. **理解二叉树特点**:二叉树的每个节点至多有两个子节点,它允许快速查找、插入...
本实验探讨了两种常见的自平衡二叉查找树——红黑树(Red-Black Tree)和二叉搜索树(Binary Search Tree),并用C语言实现了这两种数据结构,同时进行了性能比较。 首先,我们要理解二叉搜索树的基本特性。二叉...
本篇文章将深入探讨数据结构中的一个重要概念——二叉平衡树,特别是其在维持数据高效查找性能方面的关键作用。 在介绍二叉平衡树之前,我们先来回顾一下二叉查找树(Binary Search Tree,简称BST)的基本概念。...
数据结构中的树形查找是一种在树形数据结构中搜索特定元素的方法。在这个示例中,我们看到的是一个二叉搜索树(Binary Search Tree, BST)的实现,它是一种特殊的二叉树,其中每个节点的左子树只包含小于当前节点值...