二叉查找树

学习《算法导论》,学着写了二叉查找树。收获不少。

很多东西需要系统的学习呀。

  1. /********************************************************************
  2.     created:    2008/12/09
  3.     created:    9:12:2008   20:57
  4.     file base:  Main
  5.     file ext:   cpp
  6.     author:     Ai
  7.     
  8.     purpose:    练习二叉查找树
  9. *********************************************************************/
  10. #include <iostream>
  11. #include <algorithm>
  12. using namespace std;
  13. template<class T>
  14. class BSTree
  15. {
  16.     struct Node 
  17.     {
  18.         Node* left;
  19.         Node* right;
  20.         Node* parent;
  21.         T key;
  22.         Node(T k,Node* l,Node* r,Node* p):
  23.         key(k),left(l),right(r),parent(p){}
  24.     };
  25.     Node* root;
  26.     
  27. public:
  28.     //构造函数
  29.     BSTree(T date,Node* l = NULL,Node* r = NULL,Node* p = NULL):
  30.     root(new Node(date,l,r,p)){}
  31.     //析构函数
  32.     ~BSTree()
  33.     {
  34.         DeleteTree(root);
  35.     }
  36.     Node* Insert(T date)
  37.     {
  38.         Node* Target = new Node(date,NULL,NULL,NULL);//需要插入的结点
  39.         Node* NowParent = NULL;//存储父结点
  40.         Node* NowNode = root;//用于遍历的结点
  41.         while(NowNode != NULL)//查找可插入的位置
  42.         {
  43.             NowParent = NowNode;
  44.             if(Target->key > NowNode->key)
  45.                 NowNode = NowNode->right;
  46.             else
  47.                 NowNode = NowNode->left;
  48.         }
  49.         if(NowParent == NULL)//如果NowParent值为NULL,说明该树为空
  50.         {
  51.             root = Target;
  52.             return root;
  53.         }
  54.         else//将目标结点插入到指定位置
  55.         {
  56.             Target->parent = NowParent;
  57.             if(Target->key > NowParent->key)
  58.                 NowParent->right = Target;
  59.             else
  60.                 NowParent->left = Target;
  61.             return Target;
  62.         }
  63.     }
  64.     Node* SearchNode(Node* NowNode,const T date)
  65.     {
  66.         if(NowNode == NULL || NowNode->key == date)//未找到返回NULL,找到返回该结点位置
  67.             return NowNode;
  68.         if(date > NowNode->key)
  69.             SearchNode(NowNode->right,date);
  70.         else
  71.             SearchNode(NowNode->left,date);
  72.     }
  73.     Node* Max(Node* Target)
  74.     {
  75.         while(Target->right != NULL)
  76.             Target = Target->right;
  77.         return Target;
  78.     }
  79.     Node* Min(Node* Target)
  80.     {
  81.         while(Target->left != NULL)
  82.             Target = Target->left;
  83.         return Target;
  84.     }
  85.     void Print(const Node* TRoot) const//中序遍历输出
  86.     {
  87.         if(TRoot)
  88.         {
  89.             Print(TRoot->left);
  90.             //copy(&TRoot->key,&TRoot->key+1,ostream_iterator<T>(cout));
  91.             cout<<TRoot->key<<endl;
  92.             Print(TRoot->right);
  93.         }
  94.     }
  95.     const Node* GetRoot() const
  96.     {
  97.         return root;
  98.     }
  99.     void DeleteTree(Node* TRoot)
  100.     {
  101.         if(TRoot)
  102.         {
  103.             DeleteTree(TRoot->left);
  104.             DeleteTree(TRoot->right);
  105.             delete TRoot;
  106.             TRoot = NULL;
  107.         }
  108.     }
  109.     Node* Successor(Node* x)
  110.     {
  111.         if(x->right != NULL)//如果x结点存在有子女结点。那么返回其右子树最小结点
  112.             return Min(x->right);
  113.         Node* y = x->parent;
  114.         while(y != NULL && x == y->right)//x没有右子女结点,那么向上查找直到找到某一结点是其父结点的左结点
  115.         {
  116.             x = y;
  117.             y = y->parent;
  118.         }
  119.         return y;
  120.     }
  121.     void DeleteNode(T date)
  122.     {
  123.         Node* x = NULL;
  124.         Node* y = NULL;
  125.         Node* z = SearchNode(root,date);
  126.         if(z->left == NULL || z->right == NULL)//确定要删除的结点y,该结点y或者是输入结点z,或者是z的后继
  127.             y = z;
  128.         else
  129.             y = Successor(z);
  130.         if(y->left != NULL)
  131.             x = y->left;
  132.         else
  133.             x = y->right;
  134.         if(x != NULL)//修改y->parenet和x中的指针将y删除
  135.             x->parent = y->parent;
  136.         if(y->parent == NULL)
  137.             root = x;
  138.         else if(y == y->parent->left)
  139.             y->parent->left = x;
  140.         else
  141.             y->parent->right = x;
  142.         if(y != z)//如果z的后继就是要被删除的结点,则将y中的内容复制到z中。
  143.             z->key = y->key;
  144.         delete y;
  145.     }
  146. };
  147. int main()
  148. {
  149.     BSTree<int> bst(15);
  150.     bst.Insert(3);
  151.     bst.Insert(5);
  152.     bst.Insert(12);
  153.     bst.Insert(10);
  154.     bst.Insert(13);
  155.     bst.Insert(6);
  156.     bst.Insert(7);
  157.     bst.Insert(16);
  158.     bst.Insert(20);
  159.     bst.Insert(18);
  160.     bst.Insert(23);
  161.     bst.Print(bst.GetRoot());
  162.     cout<<"==============================="<<endl;
  163.     bst.DeleteNode(15);
  164.     bst.Print(bst.GetRoot());
  165.     return 0;
  166. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值