Chinaunix首页 | 论坛 | 博客
  • 博客访问: 495665
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1916
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-11 22:01
个人简介

从事实时计算多年,熟悉jstorm/spark/flink/kafka/rocketMq, 热衷于开源,希望在这里和前辈们一起学习与分享,得到长足的进步!邮箱:hustfxj@gmail.com 我的githup地址是:https://github.com/hustfxj。欢迎和大家一起交流探讨问题。

文章分类

全部博文(80)

文章存档

2017年(11)

2015年(3)

2014年(33)

2013年(33)

分类: C/C++

2013-10-31 14:51:21

1. 二叉搜索树的结构

    一个二叉树的如果不为空便是由一个根节点和左右两个只树构成。

    二叉搜索树可以提供对数时间的插入和访问,其节点的放置规则是:任何一个节点的键值一定大于其左树节点的键值,而且小于其右树节点的值。
2. 二叉搜索树类的属性、方法
    属性:二叉搜索树的根节点
    方法:插入、寻找最大值、最小值、删除等
  

点击(此处)折叠或打开

  1. //*****************************************************
  2. //File: CBinarySearchTree<T>.h
  3. //Program:
  4. // 自己定义的二叉搜索树
  5. //Author:
  6. // fxj
  7. //*****************************************************

  8. #include"stdaxf.h"
  9. #include<iomanip>
  10. //数据节点BinaryNode,并没有父节点,所以这里的操作实现会与《数据导论》上的伪代码不一致
  11. //没有定义父节点的话,前驱元素和后驱元素不好找,这里就不定义该方法了
  12. template <class T>
  13. struct BinaryNode
  14. {
  15.     T value;
  16.     BinaryNode* left;
  17.     BinaryNode* right;
  18.     BinaryNode(T val,BinaryNode* lc,BinaryNode* rl):value(val),
  19.         left(lc),right(rl)
  20.     {
  21.     }
  22. };
  23. enum PrintMode{PRE=0,MID,AFT};
  24. template <class T>
  25. class CBinarySearchTree
  26. {
  27. public:
  28.     CBinarySearchTree();
  29.     ~CBinarySearchTree();
  30. private:
  31.     BinaryNode<T>* m_pRoot;
  32. public:
  33.     void makeEmpty();
  34.     void InsertNode(T &val);
  35.     void remove(const T& x);
  36.     void printTree(PrintMode mode);
  37.     const T& findmax() ;
  38.     const T& findmin() ;
  39.     BinaryNode<T>*& searchNode(const T&x) const;
  40. //因为树的方法用到了很多递归, 所以这里我们需要申明如下的私有成员函数
  41. private:
  42.     void Insert(const T &val,BinaryNode<T>* &t);
  43.     void make_empty(BinaryNode<T>* &t);
  44.     void remove(const T& x, BinaryNode<T>* &t);
  45.     void printTreeInPrev(BinaryNode<T>* t) const;
  46.     void printTreeInMid(BinaryNode<T>* t)const;
  47.     void printTreeInPost(BinaryNode<T>* t)const;

  48.     BinaryNode<T>* find_max( BinaryNode<T>* &t) const;
  49.     BinaryNode<T>* find_min( BinaryNode<T>* &t) const;
  50.     BinaryNode<T>*& search_node(const T&x,BinaryNode<T>* &t) const;
  51. };
  52. template <class T>
  53. CBinarySearchTree<T>::CBinarySearchTree<T>()
  54. {
  55.     m_pRoot=NULL;
  56. }
  57. template <class T>
  58. CBinarySearchTree<T>::~CBinarySearchTree<T>()
  59. {
  60.     makeEmpty();
  61. }
  62. template <class T>
  63. void CBinarySearchTree<T>::InsertNode(T &val)
  64. {
  65.     Insert(val,m_pRoot);
  66. }
  67. template <class T>
  68. void CBinarySearchTree<T>::Insert(const T &val,BinaryNode<T>* &t)
  69. {
  70.     if(t==NULL)
  71.      t=new BinaryNode<T>(val,NULL,NULL);
  72.     else if(val>t->value)
  73.       Insert(val,t->right);
  74.     else
  75.      Insert(val,t->left);    
  76. }
  77. template <class T>
  78. BinaryNode<T>* CBinarySearchTree<T>::find_max(BinaryNode<T>* &t) const
  79. {
  80.     BinaryNode<T>* x=t;
  81.     if(x==NULL)
  82.         return (BinaryNode<T>*)NULL; //如果一开始就为空树?别忘了
  83.     while(x->right)
  84.         x=x->right;
  85.     return x;
  86. }
  87. template <class T>
  88. BinaryNode<T>* CBinarySearchTree<T>::find_min( BinaryNode<T>* &t) const
  89. {
  90.     BinaryNode<T>* x=t;
  91.     if(x==NULL)
  92.         return (BinaryNode<T>*)NULL; //如果一开始就为空树?别忘了
  93.     while(x->left)
  94.         x=x->left;
  95.     return x;
  96. }
  97. template <class T>
  98. void CBinarySearchTree<T>::makeEmpty()
  99. {
  100.     make_empty(m_pRoot);
  101. }
  102. template <class T>
  103. void CBinarySearchTree<T>::make_empty(BinaryNode<T>* &t)
  104. {
  105.     if(t)
  106.     {
  107.     if(t->right)
  108.         make_empty(t->right);
  109.     if(t->left)
  110.         make_empty(t->left);
  111.     if(t!=NULL)
  112.      delete t;

  113.     }
  114.     t=NULL; //每一次删除,别忘了重置
  115. }
  116. template <class T>
  117. void CBinarySearchTree<T>::remove(const T& x)
  118. {
  119.     remove(x,m_pRoot);
  120. }

  121. template <class T>
  122. void CBinarySearchTree<T>::remove(const T& x, BinaryNode<T>* &t)
  123. {
  124.     if (t == NULL)
  125.         return;
  126.     if (x < t->value)
  127.         remove(x, t->left);
  128.     else if (x > t->element)
  129.         remove (x, t->right);
  130.     else // now ==
  131.     {
  132.         if (t->left != NULL &&
  133.             t->right != NULL)//two child
  134.         {
  135.             t->value = find_min(t->right)->value;
  136.             remove(t->value, t->right);
  137.         }
  138.         else
  139.         {
  140.             BinaryNode<T> *oldNode = t;
  141.             t = (t->left != NULL) ? t->left : t->right;
  142.             delete oldNode;
  143.         }
  144.     }
  145. }
  146. template <class T>
  147. BinaryNode<T>*& CBinarySearchTree<T>::search_node(const T&x,BinaryNode<T>* &t) const
  148. {
  149.     if(x==NULL||x==t->value)
  150.         return t;
  151.     if(x>t->value)
  152.         return search_node(x,t->right);
  153.     else
  154.         return search_node(x,t->left);
  155. }
  156. /*
  157.   二叉树的遍历有三种:前序,中序,后序。

  158.         前序遍历的规律是:输出根结点,输出左子树,输出右子树;
  159.         中序遍历的规律是:输出左子树,输出根结点,输出右子树;
  160.         后序遍历的规律是:输出左子树,输出右子树,输出根结点;
  161. */
  162. template <class T>
  163.  void CBinarySearchTree<T>::printTreeInPrev(BinaryNode<T>* t) const
  164. {
  165.     if (t)
  166.     {
  167.         cout<<t->value<<' ';
  168.         printTreeInPrev(t->left);
  169.         printTreeInPrev(t->right);
  170.     }
  171. }
  172. template <class T>
  173.  void CBinarySearchTree<T>::printTreeInMid(BinaryNode<T>* t) const
  174. {
  175.     if (t)
  176.     {
  177.         printTreeInMid(t->left);
  178.         cout <<t->value<<' ';
  179.         printTreeInMid(t->right);
  180.     }
  181. }
  182. template <class T>
  183.  void CBinarySearchTree<T>::printTreeInPost(BinaryNode<T>* t) const
  184. {
  185.     if (t)
  186.     {
  187.         printTreeInPost(t->left);
  188.         printTreeInPost(t->right);
  189.         cout<<t->value<<' ';
  190.     }
  191. }
  192. template <class T>
  193. void CBinarySearchTree<T>::printTree(PrintMode mode)
  194. {
  195.     switch(mode)
  196.     {
  197.     case PRE:
  198.         printTreeInPrev(m_pRoot);
  199.         break;
  200.     case MID:
  201.         printTreeInMid(m_pRoot);
  202.         break;
  203.     case AFT:
  204.         printTreeInPost(m_pRoot);
  205.         break;
  206.     default:
  207.         break;
  208.     }
  209. }
  210. template <class T>
  211. const T& CBinarySearchTree<T>::findmax()
  212. {
  213.     BinaryNode<T>* p=find_max(m_pRoot);
  214.     return p->value;
  215. }
  216. template <class T>
  217. const T& CBinarySearchTree<T>::findmin()
  218. {
  219.     BinaryNode<T>* p=find_min(m_pRoot);
  220.     return p->value;
  221. }
  222. template <class T>
  223. BinaryNode<T>*& CBinarySearchTree<T>::searchNode(const T&x) const
  224. {
  225.     search_node(x,m_pRoot);
  226. }


注意:
这里解释下为什么要重载这么多私有的成员函数。因为树的方法用到了很多递归, 所以这里我们需要重载这些私有成员函数

阅读(2697) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~