找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3377|回复: 1

【C++】C++模板实现的二叉排序(查找)树

[复制链接]

33

主题

1

回帖

561

积分

用户组: 大·技术宅

UID
580
精华
26
威望
28 点
宅币
341 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2014-12-8
发表于 2014-12-8 18:06:32 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
二叉排序树定义:
二叉排序树是这样的树,结点左边的值都小于结点的值,结点右边的值都大于结点的值,所以按照二叉树的中序遍历的话,得到的的将是按顺序排列的值。
二叉排序树的主要操作:
1:插入
插入的操作非常简单,从根结点开始,如果插入值大于根节点值,则向右遍历,如果小于根节点值,则想左遍历,知道遇到一个叶子结点为止。按插入值大于叶子则将插入值作为叶子结点的右孩子,否则左孩子。中间过程中如果遇到跟插入值相等的,则插入失败。
2:删除
关于有三种情况需要不同对待。
<1>如果是叶子结点,那么直接删除就行(注意相关的孩子指针要变成NULL)。
<2>如果要删除的结点只有左孩子或者右孩子,这样也好办,我们只需要把相应的孩子赋值          给待删除结点的双亲结点的孩子指针即可,孙子升级当儿子。
<3>如果要删除的结点既有左孩子,又有右孩子,那么情况就稍微有点麻烦,在这里我们可以采取两种策略来实现,第一种是“前驱不动,移动右孩子法”,第二种是“右孩子不动,移动前驱法”。具体如下图所示:
1.jpg
3:遍历
遍历采用递归方法,遍历的实现就很简单了。
4:清除
在清除树的所有结点的时候,采取了递归思想,判断左孩子是否为空,如果不空则清空做孩子;再判断右孩子是否为空,不为空则清空右孩子;只有当结点左右孩子结点都为空的时候,才释放该结点的空间。
5:查找
查找要利用二叉排序树的自身优点来进行,每次根据与结点的比较结果选择再继续跟左孩子比较还是跟右孩子比较。

实现代码:
BSTrees.h
  1. //BSTrees.h
  2. #ifndef DDXX_BSTREES_H
  3. #define DDXX_BSTREES_H
  4. #include <iostream>
  5. using namespace std;
  6. template<typename Type>
  7. class BSTrees
  8. {
  9. public:
  10.         BSTrees();
  11.         ~BSTrees();
  12. public:
  13.         struct Node
  14.         {
  15.                 Type        e;
  16.                 Node*        leftChild;
  17.                 Node*        rightChild;
  18.                 Node()
  19.                 {
  20.                 }
  21.                 Node(Type _e)
  22.                 {
  23.                         e                        = _e;
  24.                         leftChild        = NULL;
  25.                         rightChild        = NULL;
  26.                 }
  27.         };
  28. public:
  29.         bool        insert(Type e);
  30.         bool        erase1(Type e);
  31.         bool        erase2(Type e);
  32.         void        clear();
  33.         bool        isEmpty();
  34.         int                getLength();
  35.         Node*        find(Type e);
  36.         Node*        getRoot();
  37.         Node*        getParent(Node* p);
  38.         void        traverse(Node* ptr);
  39. private:
  40.         void        clears(Node* &p);
  41. private:
  42.         Node*        m_root;
  43.         int                m_Length;
  44. };

  45. template<typename Type> BSTrees<Type>::BSTrees()
  46. {
  47.         m_root = NULL;
  48.         m_Length = 0;
  49. }

  50. template<typename Type> bool BSTrees<Type>::insert(Type e)
  51. {
  52.         Node* ptr = new Node(e);
  53.         if ( ptr == NULL )
  54.         {
  55.                 cout<<"Allocate memory for the element failed"<<endl;
  56.                 return false;
  57.         }

  58.         if( m_root == NULL)
  59.         {
  60.                 m_root = ptr;
  61.                 m_Length++;
  62.                 return true;
  63.         }

  64.         Node* p                        = m_root;
  65.         Node* pParent        = m_root;
  66.         while( p != NULL)
  67.         {
  68.                 if( e == p->e)
  69.                 {
  70.                         cout<<"the element is already exist"<<endl;
  71.                         return false;
  72.                 }

  73.                 pParent = p;
  74.                 if( e > p->e)
  75.                 {
  76.                         p = p->rightChild;
  77.                 }
  78.                 else
  79.                 {
  80.                         p = p->leftChild;
  81.                 }
  82.         }
  83.        
  84.         if( e < pParent->e )
  85.         {
  86.                 pParent->leftChild = ptr;
  87.         }
  88.         if( e > pParent->e)
  89.         {
  90.                 pParent->rightChild = ptr;
  91.         }

  92.         m_Length++;
  93.         return true;
  94. }

  95. template<typename Type> bool BSTrees<Type>::erase1(Type e)
  96. {
  97.         Node *p = find(e);
  98.         if ( p == NULL )
  99.         {
  100.                 cout<<"There's no this element to delete"<<endl;
  101.                 return false;
  102.         }

  103.         if ( p->leftChild == NULL)
  104.         {
  105.                 Node* pParent = getParent(p);
  106.                 if( pParent->leftChild == p )
  107.                         pParent->leftChild = p->rightChild;
  108.                 else
  109.                         pParent->rightChild = p->rightChild;
  110.                 delete p;
  111.                 p = NULL;

  112.                 m_Length--;
  113.                 return true;
  114.         }

  115.         if ( p->rightChild == NULL)
  116.         {
  117.                 Node* pParent = getParent(p);
  118.                 if( pParent->leftChild == p)
  119.                         pParent->leftChild = p->leftChild;
  120.                 else
  121.                         pParent->rightChild = p->leftChild;
  122.                 delete p;
  123.                 p = NULL;

  124.                 m_Length--;
  125.                 return true;       
  126.         }

  127.         if ( p->leftChild != NULL && p->rightChild != NULL)
  128.         {
  129.                 Node* pParent = getParent(p);
  130.                 Node* pPre = p->leftChild;
  131.                 Node* ptmp = pPre;
  132.                 while( pPre->rightChild != NULL )
  133.                 {
  134.                         ptmp = pPre;
  135.                         pPre = pPre->rightChild;
  136.                 }
  137.                 if( ptmp != pPre)
  138.                 {        ptmp->rightChild = pPre->leftChild;
  139.                         pPre->leftChild = p->leftChild;
  140.                         pPre->rightChild = p->rightChild;
  141.                 }
  142.                 else
  143.                         pPre->rightChild = p->rightChild;

  144.                 if( pParent == NULL )
  145.                         m_root = pPre;
  146.                 else
  147.                         if( pParent->leftChild == p)  
  148.                                 pParent->leftChild = pPre;
  149.                         else
  150.                                 pParent->rightChild = pPre;
  151.                
  152.                 delete p;
  153.                 p = NULL;

  154.                 m_Length--;
  155.                 return true;
  156.         }
  157.        
  158. }

  159. template<typename Type> bool        BSTrees<Type>::erase2(Type e)
  160. {
  161.         Node *p = find(e);
  162.         if ( p == NULL )
  163.         {
  164.                 cout<<"There's no this element to delete"<<endl;
  165.                 return false;
  166.         }

  167.         if ( p->leftChild == NULL)
  168.         {
  169.                 Node* pParent = getParent(p);
  170.                 if( pParent->leftChild == p )
  171.                         pParent->leftChild = p->rightChild;
  172.                 else
  173.                         pParent->rightChild = p->rightChild;
  174.                 delete p;
  175.                 p = NULL;

  176.                 m_Length--;
  177.                 return true;
  178.         }

  179.         if ( p->rightChild == NULL)
  180.         {
  181.                 Node* pParent = getParent(p);
  182.                 if( pParent->leftChild == p)
  183.                         pParent->leftChild = p->leftChild;
  184.                 else
  185.                         pParent->rightChild = p->leftChild;
  186.                 delete p;
  187.                 p = NULL;

  188.                 m_Length--;
  189.                 return true;       
  190.         }
  191.         if( p->leftChild != NULL && p->rightChild != NULL)
  192.         {
  193.                 Node* pParent = getParent(p);
  194.                 Node* ptr = p->leftChild;
  195.                 while( ptr->rightChild != NULL )
  196.                         ptr = ptr->rightChild;
  197.                 ptr->rightChild = p->rightChild;

  198.                 if( pParent == NULL )
  199.                         m_root = p->leftChild;
  200.                 else
  201.                         if(pParent->leftChild == p)
  202.                                 pParent->leftChild = p->leftChild;
  203.                         else
  204.                                 pParent->rightChild = p->leftChild;
  205.                 delete p;
  206.                 p = NULL;
  207.                 m_Length--;
  208.                 return true;
  209.         }
  210. }

  211. template<typename Type> void        BSTrees<Type>::clear()
  212. {
  213.         if( m_root == NULL )
  214.                 return;
  215.         clears(m_root);
  216.         m_root = NULL;
  217. }

  218. template<typename Type> void         BSTrees<Type>::clears(Node* &p)
  219. {
  220.         if(p->leftChild != NULL)
  221.         {
  222.                 clears(p->leftChild);
  223.                 p->leftChild = NULL;
  224.         }
  225.         if(p->rightChild != NULL)
  226.         {
  227.                 clears(p->rightChild);
  228.                 p->rightChild = NULL;
  229.         }
  230.         delete p;
  231.         p = NULL;
  232.         m_Length--;
  233.        
  234. }
  235. template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::getRoot()
  236. {
  237.         return m_root;
  238. }
  239. template<typename Type> int                BSTrees<Type>::getLength()
  240. {
  241.         return m_Length;
  242. }
  243. template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::getParent(Node* p)
  244. {
  245.         if( p == m_root)
  246.                 return NULL;
  247.         Node* ptr = m_root;
  248.         Node* ptf = ptr;
  249.         while( ptr != NULL )
  250.         {
  251.                 if ( ptr->e == p->e )
  252.                         return ptf;
  253.                 if ( ptr->e > p->e )
  254.                 {
  255.                         ptf = ptr;
  256.                         ptr = ptr->leftChild;
  257.                 }
  258.                 else
  259.                 {
  260.                         ptf = ptr;
  261.                         ptr = ptr->rightChild;
  262.                 }
  263.         }

  264. }

  265. template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::find(Type e)
  266. {
  267.         Node* ptr = m_root;

  268.         while(ptr != NULL)
  269.         {
  270.                 if ( ptr->e == e )
  271.                         return ptr;
  272.                 if ( ptr->e > e )
  273.                         ptr = ptr->leftChild;
  274.                 else
  275.                         ptr = ptr->rightChild;
  276.         }
  277.         if ( ptr == NULL )
  278.                 return NULL;
  279. }

  280. template<typename Type> void BSTrees<Type>::traverse(Node* ptr)
  281. {
  282.         if( ptr == NULL )
  283.                 return;
  284.         if( ptr->leftChild != NULL )
  285.                 traverse(ptr->leftChild);
  286.         cout<<"Element value:"<<ptr->e<<endl;
  287.         if( ptr->rightChild != NULL )
  288.                 traverse(ptr->rightChild);
  289. }

  290. template<typename Type> BSTrees<Type>::~BSTrees()
  291. {
  292.         clear();
  293. }
  294. #endif
复制代码
main.cpp
  1. //main.cpp
  2. #include <iostream>
  3. #include "BSTrees.h"
  4. using namespace std;
  5. void main()
  6. {
  7.         cout<<"************************test BSTree insert***********************"<<endl;
  8.         BSTrees<int> Bst;
  9.         int Arr[9] = {6,2,8,4,10,0,12,16,14};
  10.         for (int i=0;i<9;i++)
  11.                 Bst.insert(Arr[i]);
  12.         Bst.traverse(Bst.getRoot());
  13.         cout<<"Tree's length is:"<<Bst.getLength()<<endl;

  14.         cout<<"************************test BSTree erase1***********************"<<endl;
  15.         //Bst.erase1(6);
  16.         //Bst.erase1(16);
  17.         //Bst.erase1(10);
  18.         //Bst.erase1(8);
  19.         Bst.erase2(6);
  20.         Bst.erase2(16);
  21.         Bst.erase2(10);
  22.         Bst.erase2(8);
  23.         Bst.traverse(Bst.getRoot());
  24.         cout<<"Tree's length is:"<<Bst.getLength()<<endl;

  25.         Bst.clear();
  26.         Bst.traverse(Bst.getRoot());
  27.         cout<<"Tree's length is:"<<Bst.getLength()<<endl;
  28. }
复制代码
测试结果:
1.jpg
回复

使用道具 举报

1

主题

4

回帖

19

积分

用户组: 初·技术宅

UID
455
精华
0
威望
1 点
宅币
12 个
贡献
0 次
宅之契约
0 份
在线时间
3 小时
注册时间
2014-8-27
发表于 2014-12-8 20:31:27 | 显示全部楼层
这是在屠版么。。。
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-5-1 13:21 , Processed in 0.041589 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表