#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++实现的更多相关文章

  1. 数据结构:二叉查找树(C语言实现)

    数据结构:二叉查找树(C语言实现) ►写在前面 关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储 说明: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1.若其左子树不空,则左子树上 ...

  2. 数据结构笔记--二叉查找树概述以及java代码实现

    一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...

  3. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  4. 平衡二叉查找树(AVL)的理解与实现

    AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...

  5. 二叉查找树 C++实现(含完整代码)

    一般二叉树的查找是通过遍历整棵二叉树实现,效率较低.二叉查找树是一种特殊的二叉树,可以提高查找的效率.二叉查找树又称为二叉排序树或二叉搜索树. 二叉查找树的定义 二叉排序树(Binary Search ...

  6. 数据结构——二叉查找树、AVL树

    二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...

  7. Java for LintCode 验证二叉查找树

    给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值.    节点的右子树中的值要严格大于该节点的值.    左右子树也必须是二叉查找树. ...

  8. 数据结构和算法 – 9.二叉树和二叉查找树

      9.1.树的定义   9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...

  9. 二叉树-二叉查找树-AVL树-遍历

    一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...

  10. 二叉查找树的Java实现

    为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思路: [1] 关于容器与封装.封装,是一种非常重要的系统设计思想:无论是面向过程的函数,还 ...

随机推荐

  1. 如何使用门罗币远程节点remote node?

    当使用门罗币钱包的时候,都需要启动monerod,用来同步门罗币区块. 但是因为区块体积目前已经超过40G了, 所以需要花费很多天时间才能把数据同步完. 这对于使用门罗币非常的不方便. 远程节点rem ...

  2. CSS white-space属性详解

    概述 CSS的white-space属性用于指定如何处理容器中的空白字符,例如:空格( ).换行(\n).缩进(\t)等. white-space出自CSS1,适用于块状元素,具有继承性,支持IE 5 ...

  3. laravel-mix的安装

    Laravel-mix的安装 Laravel Mix 是一款前端任务自动化管理工具,使用了工作流的模式对制定好的任务依次执行.Mix 提供了简洁流畅的 API,让你能够为你的 Laravel 应用定义 ...

  4. reuters-多分类问题

    from keras.datasets import reuters import numpy as np from keras.utils.np_utils import to_categorica ...

  5. python数字常量

    数学常量 pi 数学常量 pi(圆周率,一般以π来表示) e 数学常量 e,e即自然常数(自然常数).

  6. mysql 从一个表查询数据插入另一个表或当前表

    mysql insert into 表明(uid,lng,lat) SELECT uuid,lng,lat FROM 表明

  7. 使用element-ui遇到的各种小问题

    一.Dialog对话框 1.在使用嵌套Dialog的时候,会出现遮罩层在内容的上方这种错乱情况 解决办法:http://element-cn.eleme.io/#/zh-CN/component/di ...

  8. Java_File类

    File类以抽象的方式代表文件名和目录路径.该类主要用于文件和目录的创建.查找.删除等.先来看一下File的构造方法: // 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File ...

  9. Day04.a(对象类型的转换,多态)

    对象类型的转换 Dog dog = new Dog(); 通常情况下,对象(new Dog())类型和引用(dog)类型是相同的,当引用类型和对象类型不一致时,就需要类型转换. 向上转型:将较具体的类 ...

  10. ELK搭建<一>:搭建ES集群

    1.首先进入官网下载ES,如果下载最新之前的版本 点击past releases就行了. 2.解压后进入config修改配置文件elasticsearch.yml #集群名称 cluster.name ...