二叉查找树(binary tree)——C++实现

1、什么是树?

  树是一种典型的数据结构,如下图所示。一棵树由一个称作根的节点和他的非空子树构成,每一颗子树的根节点成为根的儿子。图中,B,C,D就是根A的儿子。A就是B,C,D的父节点,E,F是B的儿子,B是E,F的父节点,A是E,F祖父节点。

2、什么是二叉查找树?

  而二叉树是树中的一种特例,他所有的节点最多只有两个儿子。而二叉查找树则是对二叉树进一步限定,他要求节点X的左子树的所有关键字都不大于X节点的关键字,他的右子树所有关键字都不小于X的关键字。下图就是一个二叉查找树。

  二叉树的平均深度为O(logN),除了makeEmpty外对二叉查找树其他操作平均时间为O(logN)。

  本文用C++实现简单的二叉查找树。其中某些函数有两个版本,一个是用于内部调用,一个是用于外部调用。绝大多数函数都是通过递归实现,这也显示出递归的强大。

  其中:clone函数的巧妙应用实现了操作符的重载

  1 /* 二叉寻找树的实现                                                                       */
  2 /************************************************************************/
  3 #ifndef BINARYSEARHTREE_H
  4 #define BINARYSEARHTREE_H
  5 
  6 //定义模板
  7 template <typename Comparable>
  8 class  BinarySearchTree
  9 {
 10 public:
 11     //构造函数
 12      BinarySearchTree()
 13      {
 14          root = new TreeNode;
 15      }
 16 
 17      //析构函数,回收内存
 18     ~ BinarySearchTree()
 19     {
 20         makeEmpty(root);
 21     }
 22 
 23     //拷贝构造函数
 24     BinarySearchTree(const BinarySearchTree& tree)
 25     {
 26         root = new TreeNode;
 27         *this = tree;
 28     }
 29 
 30     //重载赋值运算符,进行深层次拷贝
 31     BinarySearchTree& operator = (const BinarySearchTree & tree)
 32     {
 33         makeEmpty();
 34         root = clone(tree.root);      //通过clone函数完成数据拷贝
 35         return *this;
 36     }
 37 
 38     //判断树是否为空
 39     bool isEmpty() const
 40     {
 41         return (root->left == NULL) || (root->right == NULL);
 42     }
 43 
 44     //寻找最大的元素,递归实现
 45     TreeNode* findmax() const
 46     {
 47         if (root == NULL)
 48         {
 49             return NULL;
 50         }
 51         if (root->right == NULL)
 52         {
 53             return root;
 54         }
 55         root->right->findmax();
 56     }
 57 
 58     //寻找最小的元素,循环实现
 59     TreeNode* findmin() const
 60     {
 61         TreeNode* temp = root;
 62         if (temp == NULL)
 63         {
 64             return NULL;
 65         }
 66         while (temp->left == NULL)
 67         {
 68             temp = temp->left;
 69         }
 70         return temp->element;
 71     }
 72 
 73 
 74     //查找,调用内部版本
 75     bool find(const Comparable & object) const
 76     {
 77         return find(object, root);
 78     }
 79 
 80     //插入,调用内部版本
 81     void insert(const Comparable & object)
 82     {
 83         return insert(object, root);
 84     }
 85 private:
 86     struct TreeNode       //树节点结构体
 87     {
 88         Comparable element;    //节点关键字
 89         TreeNode* left;             //左儿子节点指针
 90         TreeNode* right;           //右儿子节点指针
 91 
 92         TreeNode(Comparable c = Comparable(), TreeNode* l = NULL, TreeNode* r = NULL)
 93             :element(c), left(l), right(r){ }
 94     };
 95 
 96     TreeNode* root;     //树的根节点指针
 97 
 98 
 99     /* 二叉查找树的查找,采用内部版本和外部版本是为了解决外部版本不能访问成员变量的问题*/
100     bool find(const Camparable & object, TreeNode* t) const
101     {
102         if (t == NULL)
103         {
104             return false;
105         }
106         //递归调用
107         if (root->element >object)
108         {
109             find(object, root->right);
110         }
111         else if (root->element < object)
112         {
113             find(object, root->left);
114         }
115         else
116         {
117             return true;
118         }
119     }
120 
121     /*插入函数*/
122     void insert(const Comparable & object, TreeNode* t)
123     {
124         //分配一个结点空间
125         if (t == NULL)
126         {
127             t = new TreeNode(object);
128             return;
129         }
130         //递归插入
131         if (root->element > object)
132         {
133             insert(object, t->left);
134         } 
135         else if(root->element < object)
136         {
137             insert(object, t->right);
138         }
139         else
140         {
141             //do nothing
142         }
143     }
144 
145     //删除节点
146     void remove(const Comparable & object, TreeNode* t)
147     {
148         //判断是否为空
149         if (t == NULL)
150         {
151             return;
152         }
153         //递归调用左右儿子
154         if (t->element >object)
155         {
156             remove(object, t->right);
157         }
158         else if (t->element < object)
159         {
160             remove(object, t->left);
161         }
162         //找到对象
163         else if(root->left != NULL && root->right != NULL)   //处理有两个儿子的情况
164         {
165              Comparable ret = findmin(root->right)->element;  //找到右子树中最小的那个,代替删除的节点
166              t->element = ret;
167              remove(ret, t->right);   //删除那个子节点
168         }
169         else         //处理一个儿子的情况
170         {
171             TreeNode* old = t;
172             t = (t->left != NULL) ? t->left : t->right;
173             delete old;
174         }
175     }
176 
177     void makeEmpty(TreeNode* t)
178     {
179         if (t == NULL)
180         {
181             return;
182         }
183         makeEmpty(t->left);
184         makeEmpty(t->right);
185         delete t;
186         t = NULL;
187     }
188 
189     TreeNode * clone( TreeNode* t) const
190     {
191         if (t == NULL)
192         {
193             return NULL;
194         }
195         return new TreeNode(t->element, t->left, t->right);
196     }
197 };
198 
199 #endif

 

转载于:https://www.cnblogs.com/liuteng/p/6015412.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值