二叉查找树的实现

  二叉查找树是满足以下条件的二叉树:

1.左子树上的所有节点值均小于根节点值,

2.右子树上的所有节点值均不小于根节点值,

3.左右子树也满足上述两个条件。

  二叉查找树的插入过程如下:

1.若当前的二叉查找树为空,则插入的元素为根节点,2.若插入的元素值小于根节点值,则将元素插入到左子树中,3.若插入的元素值不小于根节点值,则将元素插入到右子树中。

  二叉查找树的删除,分三种情况进行处理:

  1.p为叶子节点,直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点),如图a。

  2.p为单支节点(即只有左子树或右子树)。让p的子树与p的父亲节点相连,删除p即可;(注意分是根节点和不是根节点);如图b。

  3.p的左子树和右子树均不空。找到p的后继y,因为y一定没有左子树,所以可以删除y,并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替p的值;或者方法二是找到p的前驱x,x一定没有右子树,所以可以删除x,并让x的父亲节点成为y的左子树的父亲节点。如图c。

1. z结点没有孩子。

  如下图a所示,我们要删除值为13的结点,因为结点没有孩子,所以删除之后不会影响到二叉树的整体性质,也就是说,直接将13这个结点删除即可,如图a所示,从左边的二叉树删除13这个点之后变到右边的二叉树。

  2. z结点有一个孩子。

  如下图b所示,要删除的值为16的结点有一个孩子,而且是右孩子,那么从图上来看,如果,我们将16去掉,然后把以20为结点的子树作为15的右子树,那么整棵树还是符合二叉查找树的性质的,因此,有一个孩子的结点的删除操作,就是要将其孩子作为其父结点的孩子即可。如图b所示。

  3. z结点有两个孩子。

  如下图c所示,要删除的值为5的结点,有两个孩子,删除之后肯定整棵树就不符合二叉查找树的性质了,因此要进行调整,我们发现,将5的后继,值为6的结点来放到5的位置,然后将6的孩子7作为6的父结点10的孩子,如下图c所示,我们要删除的是z结点,而我们实际要删除y结点,并替换z结点。这里需要注意的一点是,如果一个结点有右孩子,则该结点的后继,至多有一个子女,而且是右孩子。因为假如该结点的后继有左孩子和右孩子,那么其左孩子的值肯定是介于该结点和其后继之间的,那么按照二叉查找树的性质,这个左孩子就应该是该结点的后继,所以,这与原先的后继相互矛盾,因此,结论成立。

tree.h

 1         /*二叉查找树的类型声明*/
 2         typedef int ElementType;
 3
 4 /* START: fig4_16.txt */
 5         #ifndef _Tree_H
 6         #define _Tree_H
 7
 8         struct TreeNode;
 9         typedef struct TreeNode *Position;
10         typedef struct TreeNode *SearchTree;
11
12         SearchTree MakeEmpty( SearchTree T );
13         Position Find( ElementType X, SearchTree T );
14         Position FindMin( SearchTree T );
15         Position FindMax( SearchTree T );
16         SearchTree Insert( ElementType X, SearchTree T );
17         SearchTree Delete( ElementType X, SearchTree T );
18         ElementType Retrieve( Position P );
19
20         #endif  /* _Tree_H */
21
22 /* END */

tree.c

  1         #include "tree.h"
  2         #include <stdlib.h>
  3         #include "fatal.h"
  4
  5         struct TreeNode
  6         {
  7             ElementType Element;
  8             SearchTree  Left;
  9             SearchTree  Right;
 10         };
 11
 12 /* START: fig4_17.txt */
 13
 14         /*让二叉查找树为空*/
 15         SearchTree
 16         MakeEmpty( SearchTree T )
 17         {
 18             if( T != NULL )
 19             {
 20                 MakeEmpty( T->Left );
 21                 MakeEmpty( T->Right );
 22                 free( T );
 23             }
 24             return NULL;
 25         }
 26 /* END */
 27
 28 /* START: fig4_18.txt */
 29         /*找元素在二叉查找树中的位置*/
 30         Position
 31         Find( ElementType X, SearchTree T )
 32         {
 33             if( T == NULL )
 34                 return NULL;
 35             if( X < T->Element )
 36                 return Find( X, T->Left );
 37             else
 38             if( X > T->Element )
 39                 return Find( X, T->Right );
 40             else
 41                 return T;
 42         }
 43 /* END */
 44
 45 /* START: fig4_19.txt */
 46         //递归实现
 47         Position
 48         FindMin( SearchTree T )
 49         {
 50             if( T == NULL )
 51                 return NULL;
 52             else
 53             if( T->Left == NULL )
 54                 return T;
 55             else
 56                 return FindMin( T->Left );
 57         }
 58 /* END */
 59
 60 /* START: fig4_20.txt */
 61         //非递归实现
 62         Position
 63         FindMax( SearchTree T )
 64         {
 65             if( T != NULL )
 66                 while( T->Right != NULL )
 67                     T = T->Right;
 68
 69             return T;
 70         }
 71 /* END */
 72
 73 /* START: fig4_22.txt */
 74
 75         /*二叉查找树的插入*/
 76         SearchTree
 77         Insert( ElementType X, SearchTree T )
 78         {
 79 /* 1*/      if( T == NULL )
 80             {
 81                 /* Create and return a one-node tree */
 82 /* 2*/          T = malloc( sizeof( struct TreeNode ) );
 83 /* 3*/          if( T == NULL )
 84 /* 4*/              FatalError( "Out of space!!!" );
 85                 else
 86                 {
 87 /* 5*/              T->Element = X;
 88 /* 6*/              T->Left = T->Right = NULL;
 89                 }
 90             }
 91             else
 92 /* 7*/      if( X < T->Element )
 93 /* 8*/          T->Left = Insert( X, T->Left );
 94             else
 95 /* 9*/      if( X > T->Element )
 96 /*10*/          T->Right = Insert( X, T->Right );
 97             /* Else X is in the tree already; we‘ll do nothing */
 98
 99 /*11*/      return T;  /* Do not forget this line!! */
100         }
101 /* END */
102
103 /* START: fig4_25.txt */
104
105         /*二叉查找树的删除*/
106         /*
107           分三种情况
108           1.两个子节点
109           2.1个子节点(左节点或者右节点)
110           3.叶子节点(0个子节点)
111          */
112         SearchTree
113         Delete( ElementType X, SearchTree T )
114         {
115             Position TmpCell;
116
117             if( T == NULL )
118                 Error( "Element not found" );
119             else
120             if( X < T->Element )  /* Go left */
121                 T->Left = Delete( X, T->Left );
122             else
123             if( X > T->Element )  /* Go right */
124                 T->Right = Delete( X, T->Right );
125             else  /* Found element to be deleted */
126             if( T->Left && T->Right )  /* Two children 两个孩子*/
127             {
128                 /* Replace with smallest in right subtree */
129                 TmpCell = FindMin( T->Right );
130                 T->Element = TmpCell->Element;
131                 T->Right = Delete( T->Element, T->Right );
132             }
133             else  /* One or zero children */
134             {
135                 TmpCell = T;
136                 if( T->Left == NULL ) /* Also handles 0 children 也处理了0个孩子的情况*/
137                     T = T->Right;
138                 else if( T->Right == NULL )
139                     T = T->Left;
140                 free( TmpCell );
141             }
142
143             return T;
144         }
145 /* END */
146
147         /* 返回某个节点的元素 */
148         ElementType
149         Retrieve( Position P )
150         {
151             return P->Element;
152         }

参考资料

二叉查找树--插入、删除、查找

《算法导论》CLRS算法C++实现(十)P151 二叉查找树

二叉查找树(五)

时间: 2024-10-16 23:07:50

二叉查找树的实现的相关文章

C语言实现二叉查找树

#include<stdio.h> #include<stdlib.h> /* * 数据结构:二叉查找树,即左孩子<父节点<右孩子 * C语言实现 * 2015-9-13 */ typedef struct TreeNode *PtrToNode; typedef PtrToNode Tree; typedef PtrToNode Position; struct TreeNode { int Element; Tree Left; //节点左孩子 Tree Right

按层遍历二叉查找树

<算法>中二叉查找树一节的习题:按层遍历二叉查找树. 可以使用队列来管理二叉查找树中的节点,节点按照如下方法入队出队: 节点x入队 当队列不为空时使用队列的第一个元素first 如果节点first.left不为空则将fisrt.left入队 如果节点first.right不为空则将first.right入队 将first节点出队 /** * Created by elvalad on 2014/12/5. * 按层遍历二叉查找树 */ import java.util.Iterator; im

二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东西 1.查询值 int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else retur

二叉查找树

二叉查找(搜索)树(Binary Search Tree)又称二叉排序树(Binary Sort Tree),是基于二叉树,BST具有下列性质:1.若左子树不空,则其左子树上的所有结点的值均小于根结点的值:2.若右子树不空,则其右子树上的所有结点的值均大于根结点的值:3.左.右子树也分别为二叉查找树. 结点类 public class BinaryNode {      Integer data;      BinaryNode leftChild;      BinaryNode rightC

平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是将有向树的所有边看成无向边形成的树状图.树是一种递归的数据结构,所以我们研究树也是按照递归的方式去研究的. 2.什么是二叉树. 我们给出二叉树的递归定义如下: (1)空树是一个二叉树. (2)单个节点是一个二叉树. (3)如果一棵树中,以它的左右子节点为根形成的子树都是二叉树,那么这棵树本身也是二叉

java 二叉查找树

//接口+抽象类+实现类package wangChaoPA实习工作练习.com.进阶篇.二叉查找树; import java.util.Iterator;public interface Tree<E extends Comparable<E>>{    // 从树中删除e    boolean delete(E e); // 树的大小    int getSize(); // 中序遍历树    void inorder(); // 把e插入到tree中    boolean i

二叉查找树C++实现

二分查找树特点: (1) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3) 任意节点的左.右子树也分别为二叉查找树. (4) 没有键值相等的节点(no duplicate nodes). 前序遍历:中左右 中序遍历:左中右 序遍历:左右中 二叉查找树的重点在于如何找节点的前驱节点和后继节点 #pragma once #include <iostream> using namespace st

[二叉查找树] 二叉排序树

题目描述 输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历. 输入 输入第一行包括一个整数n(1<=n<=100).接下来的一行包括n个整数. 输出 可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,并对二叉排序树进行前序.中序和后序遍历.每种遍历结果输出一行.每行最后一个数据之后有一个空格. 样例输入 1 2 2 8 15 4 21 10 5 39 样例输出 2 2 2 8 15 8 15 15 8 21 10 5 39 5 10 21 39 5 10 39 21

图解数据结构(7)——二叉查找树及平衡二叉查找树(一共14篇)

这篇将是最有难度和挑战性的一篇,做好心理准备!十.二叉查找树(BST)前一篇介绍了树,却未介绍树有什么用.但就算我不说,你也能想得到,看我们Windows的目录结构,其实就是树形的,一个典型的分类应用.当然除了分类,树还有别的作用,我们可以利用树建立一个非常便于查找取值又非常便于插入删除的数据结构,这就是马上要提到的二叉查找树(Binary Search Tree),这种二叉树有个特点:对任意节点而言,左子(当然了,存在的话)的值总是小于本身,而右子(存在的话)的值总是大于本身. 这种特性使得我

二叉查找树 _ 二叉排序树 _ 二叉搜索树_C++

一.数据结构背景+代码变量介绍 二叉查找树,又名二叉排序树,亦名二叉搜索树 它满足以下定义: 1.任意节点的子树又是一颗二叉查找树,且左子树的每个节点均小于该节点,右子树的每个节点均大于该节点. 2.由1可推出,任意节点的左孩子小于该节点,右孩子大于该节点 以上讨论的是左(右)孩子(子树)存在的情况 它的中序遍历是一个升序的排序 在参考代码中,我们定义有: 主程序中,k代表插入或删除或查找的节点的值 root,根节点位置:a[i],第 i 号节点的值:cl[i],第 i 号节点左孩子的位置:cr