2011年软考程序员考试复习笔试知识点整理(19)

来源:微学教育网发布时间:2011-05-06

  23、二叉排序树(BST, Binary SortTree) 的C++实现

  二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。

  (1)二叉排序树定义:二叉排序树或者是空树,或者是满足如下性质的二叉树:

  ①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;

  ②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;

  ③左、右子树本身又各是一棵二叉排序树。

  上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。

  (2)二叉排序树的特点

  由BST性质可得:

  [1]二叉排序树中任一结点x,其左(右)子树中任一结点y(若存在)的关键字必小(大)于x的关键字。

  [2]二叉排序树中,各结点关键字是惟一的。 注意:实际应用中,不能保证被查找的数据集中各元素的关键字互不相同,所以可将二叉排序树定义中BST性质[1]里的"小于"改为"小于等于",或将BST性质[2]里的"大于"改为"大于等于",甚至可同时修改这两个性质。

  [3]按中序遍历该树所得到的中序序列是一个递增有序序列。

  (3)在二叉排序树上进行查找时的平均查找长度和二叉树的形态有关:

  ①在最坏情况下,二叉排序树是通过把一个有序表的n个结点依次插入而生成的,此时所得的二叉排序树蜕化为棵深度为n的单支树,它的平均查找长度和单链表上的顺序查找相同,亦是(n+1)/2。

  ②在最好情况下,二叉排序树在生成的过程中,树的形态比较匀称,最终得到的是一棵形态与二分查找的判定树相似的二叉排序树,此时它的平均查找长度大约是lgn。

  ③插入、删除和查找算法的时间复杂度均为O(lgn)。

  (4)二叉排序树和二分查找的比较

  就平均时间性能而言,二叉排序树上的查找和二分查找差不多。

  就维护表的有序性而言,二叉排序树无须移动结点,只需修改指针即可完成插入和删除操作,且其平均的执行时间均为O(lgn),因此更有效。二分查找所涉及的有序表是一个向量,若有插入和删除结点的操作,则维护表的有序性所花的代价是O(n)。当有序表是静态查找表时,宜用向量作为其存储结构,而采用二分查找实现其查找操作;若有序表里动态查找表,则应选择二叉排序树作为其存储结构。

  //二叉查找树代码

  //BTreeNode.h二叉树结点抽象类型

  #ifndefBTREENODE_H

  #defineBTREENODE_H

  #include

  //template class BTree;

  template class SortBTree;

  template class BTreeNode

  {

  //friend class BTree;

  friend class SortBTree;

  public:

  BTreeNode():lchild(NULL),rchild(NULL){ };

  BTreeNode(const T&dt,BTreeNode *lch =NULL , BTreeNode *rch = NULL)

  :data(dt),lchild(lch),rchild(rch){};

  T get_data()const {return data; };

  BTreeNode* get_lchild()const{return lchild; };

  BTreeNode* get_rchild()const{return rchild; };

  void set_data(const T& d) { data =d;};

  protected:

  private:

  T data;

  BTreeNode *lchild, *rchild;

  };

  #endif

  /************************************************************************

  *SortBTree.h

  * 根据给定的字符串构造一个排序二叉树

  * 从排序二叉树中寻找最大值,最小值,不存在时抛出invalid_argument异常

  * 从排序二叉树中删除某一元素,不存在时抛出invalid_argument 异常

  * 往排序二叉树中添加一个新元素

  ************************************************************************/