#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. 关于js dtGrid报错长度的问题

    错误js截图 Uncaught TypeError: Cannot read property 'length' of undefined 翻译:Uncaught TypeError:无法读取未定义的 ...

  2. Repeater取不到服务端控件

    <td>      <asp:Button ID="Button1" runat="server" Text="查看" O ...

  3. 不同IDE对maven项目静态资源处理

    今天自己构建maven管理的web项目,参照另一位兄弟的代码,发现他的静态资源,也就是html.js之类的文件是在src/main/resource目录下的,我的在src/main/resource目 ...

  4. vue组件通讯方法汇总(在不使用vuex的情况下)

    前三种是父子组件通讯,最后一种是平级组件.

  5. 产品研发不等待 i.MX6Q全新推出增强版本 官方店铺下单双重优惠

    迅为全新推出PLUS版本的i.MX6Q方案,版本介绍:它是NXP公司全新推出的i.MX6Q增强版新品,显著增强了图形和存储器性能,面向较高图形性能的先进消费电子.汽车和工业多媒体应用的多核平台.

  6. easyui datagrid使用按钮

    $('#datagrid').datagrid({ border:false, fitColumns:true, singleSelect: true, url:url, columns:[[ {fi ...

  7. npm 如何安装npm包

    1.每个插件或者组件都会在官方网站有教程. 以https://v4.bootcss.com 为例 2.vuetify的 3.moment 的库

  8. @PostConstruct和@PreDestroy注解

    从Java EE5规范开始,Servlet增加了两个影响Servlet生命周期的注解(Annotation):@PostConstruct和@PreConstruct.这两个注解被用来修饰一个非静态的 ...

  9. Go语言--数组、切片、

    3.1 数组--固定大小的连续空间 3.1.1 声明数组 写法 var 数组变量名 [元素数量]T 说明: 变量名就是使用时的变量 元素的数量可以是表达式,最后必须为整型数值 T 可是是任意基本类型, ...

  10. 修改Maven仓库路径

    我自己新建的地址:D:\apache-maven-3.6.0\repository 找到:localRepository,修改为自定义的位置 在IDEA里面进行配置 这样项目的maven仓库地址就修改 ...