二叉查找树的C++实现
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
////////
template <typename T>
class BinarySearchTree{
/////////
private:
struct BinaryNode{
T element;
BinaryNode* left;
BinaryNode* right;
BinaryNode(T ele, BinaryNode* lt, BinaryNode* rt): element(ele),
left(lt), right(rt){}
};
BinaryNode* root;
BinaryNode* clone(BinaryNode* t)const{
if(t == NULL)
return NULL;
return new BinaryNode(t->element, clone(t->left), clone(t->right));
}
void makeEmpty(BinaryNode* &t){//mind here
if(t != NULL){
makeEmpty(t->left);
makeEmpty(t->right);
delete t;//mind here...
}
t = NULL;
}
////////
public:
BinarySearchTree(){
root = new BinaryNode(, NULL, NULL);
}
BinarySearchTree(const BinarySearchTree& rhs): root(clone(rhs.root)){}
const BinarySearchTree& operator=(const BinarySearchTree& rhs){
if(this != &rhs){
makeEmpty(this->root);
root = clone(rhs.root);
}
return *this;
}
~BinarySearchTree(){
if(root != NULL)
makeEmpty(root);
}
/// concrete algorithms
BinaryNode* findMax(const BinaryNode* t){
if(t == NULL)
return NULL;
if(t->right == NULL)
return t;
return findMax(t->right);
}
///
BinaryNode* findMin(const BinaryNode* t){
if(t == NULL)
return NULL;
if(t->left == NULL)
return t;
return findMin(t->left);
} bool isBinarySearchTree(const BinaryNode* root){
if(root != NULL){
if(root->right == NULL && root->left == NULL)
return true;
if(root->left != NULL && root->right == NULL
&& root->left->element < root->element)
return isBinarySearchTree(root->left);
if(root->left == NULL && root->right != NULL
&& root->element < root->right->element)
return isBinarySearchTree(root->right);
if(root->left && root->right
&& root->element < root->right->element
&& root->left->element < root->element)
return isBinarySearchTree(root->left) && isBinarySearchTree(root->right);
return false;
}
return true;
}
void numofNode(const BinaryNode* root, int& num){
if(root != NULL){
if(root->left == NULL && root->right == NULL)
++num;
if(root->left != NULL && root->right == NULL){
++num;
numofNode(root->left, num);
}
if(root->left == NULL && root->right != NULL){
++num;
numofNode(root->right, num);
}
if(root->left != NULL && root->right !=NULL){
++num;
numofNode(root->left, num);
numofNode(root->right, num);
}
}
} void numofLeafNode(const BinaryNode* root, int& num){
if(root != NULL){
if(root->left == NULL && root->right == NULL){
++num;
}
if(root->left != NULL && root->right == NULL){
numofLeafNode(root->left, num);
}
if(root->left == NULL && root->right != NULL){
numofLeafNode(root->right, num);
}
if(root->left != NULL && root->right !=NULL){
numofLeafNode(root->left, num);
numofLeafNode(root->right, num);
}
}
} void numoffullNode(const BinaryNode* root, int& num){
if(root != NULL){
if(root->left == NULL && root->right == NULL){
++num;
}
if(root->left != NULL && root->right == NULL){
numoffullNode(root->left, num);
}
if(root->left == NULL && root->right != NULL){
numoffullNode(root->right, num);
}
if(root->left != NULL && root->right !=NULL){
numofLeafNode(root->left, num);
numofLeafNode(root->right, num);
}
}
} ////
bool contains(const T& x, const BinaryNode* t){
if(t == NULL)
return false;
if(x < t->element)
return contains(x, t->left);
else if(x > t->right)
return contains(x, t->right);
else
return true;
}
///
void insert_s(const T& x, BinaryNode* & t){
if(t == NULL)
t = new BinaryNode(x, NULL, NULL);
if(x < t->element)
insert_s(x, t->left);
else if(x > t->element)
insert_s(x, t->right);
else
;
}
void insert(const T& x){
insert_s(x, root);
}
///
void remove_s(const T& x, BinaryNode* & t){
if(t == NULL)
return;
if(x < t->element)
remove_s(x, t->left);
else if(x, t->element)
remove_s(x, t->right);
else if(t->right != NULL && t->left != NULL){
t->element = findMin(t->right)->element;
remove_s(t->element, t->right);
}
else{
BinaryNode* old = t;
t = (t->left != NULL)? t->left: t->right;
delete old;
}
}
void remove(const T& x){
remove_s(x, root);
}
///
void printTree_s(const BinaryNode* t){
if(t != NULL){
printTree_s(t->left);
printTree_s(t->right);
cout << t->element << endl;
}
}
void printTree(){
printTree_s(root);
} //前序遍历
void PreOrderTraverseRec(const BinaryNode* root){
if(root != NULL){
cout << root->element << endl;
PreOrderTraverseRec(root->left);
PreOrderTraverseRec(root->right);
}
}
void PreOrderTraverseNonRec_1(const BinaryNode* root){
if(root == NULL){
cout << "enmpty tree...\n";
}
else{
stack<BinaryNode*> st;
BinaryNode* curr = root;
st.push(curr);
while(!st.empty()){
curr = st.top();
cout << curr->element << endl;
st.pop();
if(curr->right != NULL)
st.push(curr->right);
if(curr->left != NULL)
st.push(curr->left);
}
}
} void PreOrderTraverseNonRec_2(const BinaryNode* root){
if(root == NULL)
cout << "empty tree...\n";
else{
stack<BinaryNode*> st;
BinaryNode* curr = root;
while(!st.empty() || curr != NULL){
while(curr != NULL){
st.push(curr);
cout << curr->element << endl;
curr = curr->left;
}
if(!st.empty()){
curr = st.top();
st.pop();
curr = curr->right;
}
}
}
}
void PreOrderTraverseMorris(const BinaryNode* root){
BinaryNode* curr = root;
BinaryNode* pre = NULL;
while(curr != NULL){
if(curr->left == NULL){
cout << curr->element << endl;
curr = curr->right;
}
else{
pre = curr->left;
while(pre->right != NULL && pre->right != curr)
pre = pre->right;
if(pre->right == NULL){
cout << curr->element << endl;
pre->right = curr;
curr = curr->left;
}
else{
pre->right = NULL;
curr = curr->right;
}
}
}
} //中序遍历
void InOrderTraverselRec(const BinaryNode* root){
if(root != NULL){
InOrderTraverselRec(root->left);
cout << root->element << endl;
InOrderTraverselRec(root->right);
}
} void InOrderTraverselNonRec(const BinaryNode* root){
if(root == NULL)
cout << "empty tree...\n";
else{
stack<BinaryNode*> st;
BinaryNode* curr = root;
while(!st.empty() || curr != NULL){
while(curr != NULL){
st.push(curr);
curr = curr->left;
}
if(!st.empty()){
curr = st.top();
st.pop();
cout << curr->element << endl;
curr = curr->right;
}
}
}
}
void InOrderTraverselMorris(const BinaryNode* root){
BinaryNode* curr = root;
BinaryNode* pre = NULL;
while(curr != NULL){
if(curr->left == NULL){
cout << curr->element << endl;
curr = curr->right;
}
else{
pre = curr->left;
while(pre->right != NULL && pre->right != curr)
pre = pre->right;
if(pre->right == NULL){
pre->right = curr;
curr = curr->left;
}
else{
pre->right = NULL;
cout << curr->element << endl;
curr = curr->right;
}
}
}
}
//后续遍历
void PostOrderTraverseRec(const BinaryNode* root){
if(root != NULL){
PostOrderTraverseRec(root->left);
PostOrderTraverseRec(root->right);
cout << root->element;
}
} void PostOrderTraverseNonRec_1(const BinaryNode* root){
if(root == NULL)
cout << "empty tree...\n";
else{
stack<BinaryNode*> st;
BinaryNode* curr = root;
BinaryNode* pre = NULL;
while(!st.empty() || curr != NULL){
while(curr != NULL){
st.push(curr);
curr = curr->left;
}
if(!st.empty()){
curr = st.top();
if(curr->right == NULL || pre == curr->right){
cout << curr->element << endl;
st.pop();
pre = curr;
curr == NULL;
}
else
curr = curr->right;
}
}
}
} void PostOrderTraverseNonRec_2(const BinaryNode* root){
if(root == NULL)
cout << "empty tree...\n";
else{
stack<BinaryNode*> st;
BinaryNode* curr = root;
BinaryNode* pre = NULL;
st.push(curr);
while(!st.empty() || curr != NULL){
curr = st.top();
if((curr->left == NULL && curr->right == NULL) ||
((curr->right == NULL && pre == curr->left) ||
pre == curr->right)){
st.pop();
cout << curr->element;
pre = curr;
}
else{
if(curr->right != NULL)
st.push(curr->right);
if(curr->left != NULL)
st.push(curr->left);
}
}
}
} void PostOrderTraverseNonRec_3(const BinaryNode* root){
stack<BinaryNode*> st;
BinaryNode* curr = root;
st.push(curr);
st.push(curr);
while(!st.empty()){
curr = st.top();
st.pop();
if(!st.empty() && curr == st.top()){
if(curr->right){
st.push(curr->right); st.push(curr->right);
}
if(curr->left){
st.push(curr->left); st.push(curr->left);
}
}
else
cout << curr->element << endl;
}
}
}; int main(){
BinarySearchTree<int> lt;
lt.insert();
lt.insert();
lt.insert(-);
lt.printTree();
return ;
}
二叉查找树的C++实现的更多相关文章
- 数据结构:二叉查找树(C语言实现)
数据结构:二叉查找树(C语言实现) ►写在前面 关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储 说明: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1.若其左子树不空,则左子树上 ...
- 数据结构笔记--二叉查找树概述以及java代码实现
一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...
- codevs 1285 二叉查找树STL基本用法
C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...
- 平衡二叉查找树(AVL)的理解与实现
AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...
- 二叉查找树 C++实现(含完整代码)
一般二叉树的查找是通过遍历整棵二叉树实现,效率较低.二叉查找树是一种特殊的二叉树,可以提高查找的效率.二叉查找树又称为二叉排序树或二叉搜索树. 二叉查找树的定义 二叉排序树(Binary Search ...
- 数据结构——二叉查找树、AVL树
二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...
- Java for LintCode 验证二叉查找树
给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二叉查找树. ...
- 数据结构和算法 – 9.二叉树和二叉查找树
9.1.树的定义 9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...
- 二叉树-二叉查找树-AVL树-遍历
一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...
- 二叉查找树的Java实现
为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思路: [1] 关于容器与封装.封装,是一种非常重要的系统设计思想:无论是面向过程的函数,还 ...
随机推荐
- PostgreSql sql shell win10 下乱码解决
重现步骤: 打开 SQL Shell (psql) Server [localhost]: Database [postgres]: Port ]: Username [postgres]: psql ...
- 中文 Tex
\documentclass{article} \usepackage{ctex} \begin{document} 中文English \[E = m c^2\] \end{document} \d ...
- NPOI 读取excel的时候,时间格式的处理
excel的时间格式是:CellType.Numeric 要判断时间还需要方法:DateUtil.IsCellDateFormatted(cell)的帮助: 示例代码如下: ICell cell = ...
- 多个Fragment在一个activity中通过按钮的展示方法
fragment使用方法 1. 创建主Mainactivity extends AppCompatActivity 2. Oncreate & setContentView 3. 完成XML的 ...
- git本机服务器配置(四):git+TortoiseGit+gitblit配置本机服务器
1.配置本机git服务器 1.1 打开gitblit服务器,登录之前设置的服务页面localhost:1081 1.2.登录账号,账号在(三)中有提到. 1.3 打开用户中心 1.4 点击SSH Ke ...
- springboot2.1.3集成单节点elasticsearch6.4.0
本案例写了一个关于医生医院搜索的例子,包括求和模式下的打分(分值与相关性有关)搜索,单节点时切勿配置节点名称和节点ip.github地址:https://github.com/zhzhair/spri ...
- CVE-2018-19386:SolarWinds数据库性能分析器中反射的XSS
漏洞 在SolarWinds的11.1.457版中,"idcStateError.iwc"错误页面中存在Reflected Cross-Site Scripting漏洞,已经在版本 ...
- 使用extjs的页面弹出窗口宽度不能自适应如何解决?
1.资源趋势详情下钻页面宽度不能自适应,无法点击关闭按钮 var detailWindow = Ext.create("App.view.com.huawei.drp.qoe.vivid.C ...
- 关于 git 本地创建 SSH Key 遇到的一点问题(①file to save the key & ②the authenticity of host...)
背景 由于想测试一下 SSH Key 创建的路径(.ssh 目录路径)对于不同位置 git 项目是否有效. 比如,.ssh 默认在 C:\[users]\[username] 目录下,而项目 proj ...
- C语言的数组指针
数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element).数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存.以int arr[] = { 99, ...