问题叙述性说明:

1.binary search tree它是一种二进制树的。对于key值。比当前节点左孩子少大于右子。

2.binary search tree不是自平衡树。所以,当插入数据不是非常随机时候,性能会接近O(N)。N是树中节点数目;

3.理想状态下。时间复杂度是O(lgN), N是树中节点的数目;

4.以下给出一个简单的实现,并比較其和STL map的性能。一样的操作,大约耗时为STL map 的2/3。

代码例如以下:

  1. #ifndef _BINARY_SEARCH_TREE_H_
  2. #define _BINARY_SEARCH_TREE_H_
  3.  
  4. #include <functional>
  5. #include <algorithm>
  6. #include <iostream>
  7. #include <map>
  8.  
  9. #include "windows.h"
  10.  
  11. template<class T, class V, class Cmp = std::less<T> >
  12. class BinarySearchTree
  13. {
  14. public:
  15.  
  16. // node struct
  17. typedef struct tagBSNode
  18. {
  19. T key;
  20. V value;
  21. tagBSNode* leftNode;
  22. tagBSNode* rightNode;
  23.  
  24. tagBSNode():key(), value(),
  25. leftNode(0),
  26. rightNode(0)
  27. {
  28.  
  29. }
  30.  
  31. tagBSNode( const T& _key, const V& _value ):key(_key),
  32. value(_value),
  33. leftNode(0),
  34. rightNode(0)
  35. {
  36.  
  37. }
  38.  
  39. }BSTNode, *pBSTNode;
  40.  
  41. /*
  42. * Constructor
  43. *
  44. */
  45. BinarySearchTree():m_root(0), m_size(0)
  46. {
  47.  
  48. }
  49.  
  50. /*
  51. * Copy constructor
  52. *
  53. */
  54. BinarySearchTree( const BinarySearchTree& rhs )
  55. {
  56. m_root = Clone( rhs.m_root );
  57. m_size = rhs.m_size;
  58. }
  59.  
  60. /*
  61. * Destructor
  62. *
  63. */
  64. ~BinarySearchTree()
  65. {
  66. Clear();
  67. }
  68.  
  69. /*
  70. * assignment operator overload
  71. *
  72. */
  73. BinarySearchTree& operator = ( const BinarySearchTree& rhs )
  74. {
  75. if( this != &rhs )
  76. {
  77. Clear();
  78.  
  79. m_root = Clone( rhs.m_root );
  80. m_size = rhs.m_size;
  81. }
  82.  
  83. return *this;
  84. }
  85.  
  86. /*
  87. * Clear all node
  88. *
  89. */
  90. void Clear()
  91. {
  92. Clear( m_root );
  93. m_size = 0;
  94. }
  95.  
  96. /*
  97. * check whether or not empty
  98. *
  99. */
  100. bool IsEmpty() const
  101. {
  102. return m_size == 0;
  103. }
  104.  
  105. /*
  106. * Retrieve the number of node in tree
  107. *
  108. */
  109. size_t Size() const
  110. {
  111. return m_size;
  112. }
  113.  
  114. /*
  115. *
  116. *
  117. */
  118. size_t GetSize() const // only for test
  119. {
  120. return Size( m_root );
  121. }
  122.  
  123. /*
  124. * Insert key and value pair to tree
  125. *
  126. */
  127. void Insert( const T& key, const V& value )
  128. {
  129. Insert( m_root, key, value );
  130. }
  131.  
  132. /*
  133. * Delete node from tree for given key
  134. *
  135. */
  136. void Delete( const T& key )
  137. {
  138. Delete( m_root, key );
  139. }
  140.  
  141. /*
  142. * Find element from tree for given key
  143. *
  144. */
  145. V* Find( const T& key )
  146. {
  147. pBSTNode node = Find( m_root, key );
  148. if( node )
  149. return &node->value;
  150.  
  151. return 0;
  152. }
  153.  
  154. /*
  155. * Find the the element of max key
  156. *
  157. */
  158. V* FindMax( T& key )
  159. {
  160. pBSTNode node = FindMax( m_root );
  161. if( node )
  162. {
  163. key = node->key;
  164. return &node->value;
  165. }
  166.  
  167. return 0;
  168. }
  169.  
  170. /*
  171. * Find the the element of min key
  172. *
  173. */
  174. V* FinMin( T& key )
  175. {
  176. pBSTNode node = FindMin( m_root );
  177. if( node )
  178. {
  179. key = node->key;
  180. return &node->value;
  181. }
  182.  
  183. return 0;
  184. }
  185.  
  186. /*
  187. * inoder traversal
  188. *
  189. */
  190. void InorderVisitor( void (*visitor)( const T&, const V& ) )
  191. {
  192. InorderVisitor( m_root, visitor );
  193. }
  194.  
  195. /*
  196. * preoder traversal
  197. *
  198. */
  199. void PreOrderVisitor( void (*visitor)( const T&, const V& ) )
  200. {
  201. PreOrderVisitor( m_root, visitor );
  202. }
  203.  
  204. /*
  205. * postoder traversal
  206. *
  207. */
  208. void PostOrderVisitor( void (*visitor)( const T&, const V& ) )
  209. {
  210. PostOrderVisitor( m_root, visitor );
  211. }
  212.  
  213. protected:
  214.  
  215. /*
  216. * Implement clone operation
  217. *
  218. */
  219. pBSTNode Clone( pBSTNode root )
  220. {
  221. if( 0 == root )
  222. return root;
  223.  
  224. pBSTNode node = new BSTNode( root->key, root->value );
  225. node->leftNode = Clone( root->leftNode );
  226. node->rightNode = Clone( root->rightNode );
  227.  
  228. return node;
  229. }
  230.  
  231. /*
  232. * Implement clear opreation
  233. *
  234. */
  235. void Clear( pBSTNode& root )
  236. {
  237. if( 0 == root )
  238. return;
  239.  
  240. Clear( root->leftNode );
  241. Clear( root->rightNode );
  242.  
  243. delete root;
  244. root = 0;
  245.  
  246. }
  247.  
  248. /*
  249. * Retrieve the number of node by way of recursive
  250. *
  251. */
  252. size_t Size( pBSTNode root ) const
  253. {
  254. if( 0 == root )
  255. return 0;
  256.  
  257. return 1 + Size( root->leftNode ) + Size( root->rightNode );
  258. }
  259.  
  260. /*
  261. * Implement insert operation
  262. *
  263. */
  264. void Insert( pBSTNode& root,const T& key, const V& value )
  265. {
  266. if( 0 == root )
  267. {
  268. root = new BSTNode( key, value );
  269. m_size++;
  270. }
  271.  
  272. if( root->key < key )
  273. {
  274. Insert( root->rightNode, key, value );
  275. }
  276. else if( root->key > key )
  277. {
  278. Insert( root->leftNode, key, value );
  279. }
  280. }
  281.  
  282. /*
  283. * Implement delete operation
  284. *
  285. */
  286. void Delete( pBSTNode& root, const T& key )
  287. {
  288. if( 0 == root )
  289. return;
  290.  
  291. if( root->key < key )
  292. {
  293. Delete( root->rightNode, key );
  294. }
  295. else if( root->key > key )
  296. {
  297. Delete( root->leftNode, key );
  298. }
  299. else
  300. {
  301. if( root->leftNode && root->rightNode )
  302. {
  303. pBSTNode minNode = FindMin( root->rightNode );
  304. root->key = minNode->key;
  305. root->value = minNode->value;
  306.  
  307. Delete( root->rightNode, minNode->key );
  308. }
  309. else
  310. {
  311. pBSTNode node = root;
  312. root = root->leftNode ? root->leftNode: root->rightNode;
  313.  
  314. delete node;
  315. node = 0;
  316.  
  317. m_size--; //very important
  318.  
  319. }
  320.  
  321. }
  322. }
  323.  
  324. /*
  325. * Implement find operation
  326. *
  327. */
  328. pBSTNode Find( pBSTNode root, const T& key )
  329. {
  330. if( 0 == root )
  331. return root;
  332.  
  333. if( root->key < key )
  334. {
  335. return Find( root->rightNode, key );
  336. }
  337. else if( root->key > key )
  338. {
  339. return Find( root->leftNode, key );
  340. }
  341. else
  342. {
  343. return root;
  344. }
  345. }
  346.  
  347. /*
  348. * Find implement no recursive
  349. *
  350. */
  351. pBSTNode FindUtil( pBSTNode root, const T& key )
  352. {
  353. if( 0 == root )
  354. return root;
  355.  
  356. pBSTNode cur = root;
  357. while( root )
  358. {
  359. cur = root;
  360. if( root->key < key )
  361. {
  362. root = root->rightNode;
  363. }
  364. else if( root->key > key )
  365. {
  366. root = root->leftNode;
  367. }
  368. else
  369. {
  370. break;
  371. }
  372. }
  373.  
  374. if( cur && cur->key == key )
  375. return cur;
  376.  
  377. return 0;
  378. }
  379.  
  380. /*
  381. * Implement find max element operation
  382. *
  383. */
  384. pBSTNode FindMax( pBSTNode root )
  385. {
  386. if( 0 == root )
  387. return root;
  388.  
  389. while( root->rightNode )
  390. {
  391. root = root->rightNode;
  392. }
  393.  
  394. return root;
  395. }
  396.  
  397. /*
  398. * Implement find min element operation
  399. *
  400. */
  401. pBSTNode FindMin( pBSTNode root )
  402. {
  403. if( 0 == root )
  404. return root;
  405.  
  406. while( root->leftNode )
  407. {
  408. root = root->leftNode;
  409. }
  410.  
  411. return root;
  412. }
  413.  
  414. /*
  415. * Implement inorder traversal
  416. *
  417. */
  418. void InorderVisitor( pBSTNode root, void (*visitor)( const T&, const V& ) )
  419. {
  420. if( 0 == root )
  421. return;
  422.  
  423. InorderVisitor( root->leftNode, visitor );
  424. visitor( root->key, root->value );
  425. InorderVisitor( root->rightNode, visitor );
  426. }
  427.  
  428. /*
  429. * Implement preorder traversal
  430. *
  431. */
  432. void PreOrderVisitor( pBSTNode root, void (*visitor)( const T&, const V& ) )
  433. {
  434. if( 0 == root )
  435. return;
  436.  
  437. visitor( root->key, root->value );
  438. InorderVisitor( root->leftNode, visitor );
  439. InorderVisitor( root->rightNode, visitor );
  440. }
  441.  
  442. /*
  443. * Implement postorder traversal
  444. *
  445. */
  446. void PostOrderVisitor( pBSTNode root, void (*visitor)( const T&, const V& ) )
  447. {
  448. if( 0 == root )
  449. return;
  450.  
  451. InorderVisitor( root->leftNode, visitor );
  452. InorderVisitor( root->rightNode, visitor );
  453. visitor( root->key, root->value );
  454. }
  455.  
  456. protected:
  457.  
  458. pBSTNode m_root;
  459.  
  460. size_t m_size;
  461. };
  462.  
  463. /*
  464. * Test STL map
  465. *
  466. */
  467. void TestSTLMapBST()
  468. {
  469. const int Len = 200000;
  470. //int key[Len];
  471. //int value[Len];
  472.  
  473. int* key = new int[Len];
  474. int* value = new int[Len];
  475.  
  476. for( int i = 0; i < Len; i++ )
  477. {
  478. key[i] = i;
  479. value[i] = i;
  480. }
  481.  
  482. std::random_shuffle( key, key + Len );
  483. std::random_shuffle( value, value + Len );
  484.  
  485. unsigned long start = GetTickCount();
  486.  
  487. std::map<int, int> treeObj;
  488. for( int i = 0; i < Len; i++ )
  489. {
  490. treeObj.insert( std::make_pair( key[i], value[i] ) );
  491. }
  492.  
  493. size_t count = treeObj.size();
  494.  
  495. for( int i = 0; i < Len; i++ )
  496. {
  497. std::map<int, int>::iterator iter = treeObj.find( key[i] );
  498. assert( iter != treeObj.end() );
  499. assert( iter->second == value[i] );
  500. }
  501.  
  502. for( int i = 0; i < Len; i++ )
  503. {
  504. if( !(i % 15) )
  505. {
  506. treeObj.erase( key[i] );
  507. std::map<int, int>::iterator iter = treeObj.find( key[i] );
  508. assert( iter == treeObj.end() );
  509.  
  510. }
  511. }
  512.  
  513. unsigned long interval = GetTickCount() - start;
  514. printf( " STL map consume time is %d \n", interval );
  515.  
  516. delete [] key;
  517. delete [] value;
  518.  
  519. }
  520.  
  521. /*
  522. * vistior function for output information when traversal tree
  523. *
  524. */
  525. template<class T, class V>
  526. void Visitor( const T& key, const V& value )
  527. {
  528. std::cout << "key: " << key << "," <<"value: " << value << std::endl;
  529. }
  530.  
  531. /*
  532. * unit test
  533. *
  534. */
  535. void TestBST()
  536. {
  537. const int Len = 200000;
  538. //int key[Len];
  539. //int value[Len];
  540.  
  541. int* key = new int[Len];
  542. int* value = new int[Len];
  543.  
  544. for( int i = 0; i < Len; i++ )
  545. {
  546. key[i] = i;
  547. value[i] = i;
  548. }
  549.  
  550. std::random_shuffle( key, key + Len );
  551. std::random_shuffle( value, value + Len );
  552.  
  553. unsigned long start = GetTickCount();
  554.  
  555. BinarySearchTree<int, int> treeObj;
  556. for( int i = 0; i < Len; i++ )
  557. {
  558. treeObj.Insert( key[i], value[i] );
  559. }
  560.  
  561. for( int i = 0; i < Len; i++ )
  562. {
  563. int* val = treeObj.Find( key[i] );
  564. assert( *val == value[i] );
  565. }
  566.  
  567. int minKey = -1;
  568. int* minValue = treeObj.FinMin( minKey );
  569. assert( minKey == 0 );
  570.  
  571. int maxKey = -1;
  572. int* maxValue = treeObj.FindMax( maxKey );
  573. assert( maxKey == Len - 1 );
  574.  
  575. size_t size = treeObj.Size();
  576. assert( size == Len );
  577.  
  578. int flagCount = 0;
  579. for( int i = 0; i < Len; i++ )
  580. {
  581. if( !(i % 15) )
  582. {
  583. treeObj.Delete( i );
  584. int* val = treeObj.Find( i );
  585. assert( !val );
  586.  
  587. flagCount++;
  588. }
  589. }
  590.  
  591. unsigned long interval = GetTickCount() - start;
  592. printf( " binary search tree consume time is %d \n", interval );
  593.  
  594. size = treeObj.Size();
  595. size_t count = treeObj.GetSize();
  596.  
  597. BinarySearchTree<int, int> newTreeObj;
  598. for( int i = 0; i < 10; i++ )
  599. {
  600. newTreeObj.Insert( key[i], value[i] );
  601. }
  602.  
  603. treeObj = newTreeObj;
  604. newTreeObj.Clear();
  605.  
  606. std::cout<< "begin inorder traversal " << std::endl;
  607. treeObj.InorderVisitor( Visitor<int, int> );
  608.  
  609. std::cout<< "begin postorder traversal " << std::endl;
  610. treeObj.PostOrderVisitor( Visitor<int, int> );
  611.  
  612. std::cout<< "begin preorder traversal " << std::endl;
  613. treeObj.PreOrderVisitor( Visitor<int, int> );
  614.  
  615. treeObj.Clear();
  616.  
  617. delete [] key;
  618. delete [] value;
  619. }
  620.  
  621. void TestBSTSuite()
  622. {
  623. TestSTLMapBST();
  624. TestBST();
  625. }
  626.  
  627. #endif

泛型Binary Search Tree实现,And和STL map比较的经营业绩的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. 二叉搜索树(Binary Search Tree)(Java实现)

    @ 目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  3. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  4. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  5. Leetcode: Convert sorted list to binary search tree (No. 109)

    Sept. 22, 2015 学一道算法题, 经常回顾一下. 第二次重温, 决定增加一些图片, 帮助自己记忆. 在网上找他人的资料, 不如自己动手. 把从底向上树的算法搞通俗一些. 先做一个例子: 9 ...

  6. [LeetCode] Closest Binary Search Tree Value II 最近的二分搜索树的值之二

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  7. [LeetCode] Closest Binary Search Tree Value 最近的二分搜索树的值

    Given a non-empty binary search tree and a target value, find the value in the BST that is closest t ...

  8. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  9. [LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

随机推荐

  1. MOCKITO 应用示例

    package com.paic.wms.service.auditflow.impl; import static org.junit.Assert.*; import java.util.Arra ...

  2. hdu1392 Surround the Trees 凸包

    第一次做凸包,这道题要特殊考虑下,n=2时的情况,要除以二才行. 我是从最左边的点出发,每次取斜率最大的点,一直到最右边的点. 然后从最左边的点出发,每次取斜率最低的点,一直到最右边的点. #incl ...

  3. ExtJs4 笔记(10) Ext.tab.Panel 选项卡

    本篇讲解选项卡控件. 一.基本选项卡 首先我们来定义一个基本的选项卡控件,其中每个Tab各有不同,Tab的正文内容可以有三种方式获取: 1.基本方式:通过定义html和items的方式. 2.读取其他 ...

  4. QT 多线程程序设计(也有不少例子)

    QT通过三种形式提供了对线程的支持.它们分别是,一.平台无关的线程类,二.线程安全的事件投递,三.跨线程的信号-槽连接.这使得开发轻巧的多线程Qt程序更为容易,并能充分利用多处理器机器的优势.多线程编 ...

  5. 验证码 Captcha 之大插件

    验证码 Captcha 之大插件小用 不知何年何月才能完成OADemo啊,总之还是一步一步来吧,这段时间开始着手了,先做登陆.  前段时间研究了一下在CentOS7下安装Mysql和Memcached ...

  6. 魔棒工具--RegionGrow算法简介

    原地址:http://www.cnblogs.com/easymind223/archive/2012/07/04/2576964.html ps里面的魔棒工具非常好用,是图像处理中非常常用的一个工具 ...

  7. 使用Seam Framework + JBoss 5.0 开发第一个Web应用 - 简单投票程序

    Seam这个单词的本意是缝合.连接,因而,Seam的作用即是把Java EE 规范里的JSF 和 EJB技术完美融合在一起,免去了很多胶合代码,并增强了JSF 和 EJB的很多功能.Seam的设计目标 ...

  8. 【BASH】自己主动清理rman脚本备份文件

    ************************************************************************ ****原文:blog.csdn.net/clark_ ...

  9. Python基础 - 内建函数

    什么是内建函数 在Python的手册中,名叫build-in Functions,中文可以称为内建函数. 内建函数就像dos系统的内部命令,他不依赖于外部模块,也就是说: 内建函数就是:安装好Pyth ...

  10. POJ1789 Truck History 【最小生成树Prim】

    Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18981   Accepted: 7321 De ...