二分查找树特点:

(1) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3) 任意节点的左、右子树也分别为二叉查找树。

(4) 没有键值相等的节点(no duplicate nodes)。

前序遍历:中左右

中序遍历:左中右

序遍历:左右中

二叉查找树的重点在于如何找节点的前驱节点和后继节点

#pragma once
#include <iostream>
using namespace std; template <class T>
class BSTNode
{
public:
T key;
BSTNode *parent;
BSTNode *left;
BSTNode *right; BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(p),left(l),right(r)
{ }
}; template <class T>
class BSTree
{
private:
BSTNode<T> *mRoot; public:
BSTree():mRoot(NULL){}
~BSTree(){} // 前序排序
void preOrder()
{
preOrder(mRoot);
}
void inOrder()
{
inOrder(mRoot);
}
void postOrder()
{
postOrder(mRoot);
}
// 查找二叉树中键值为key的节点
BSTNode<T>* SearchKey(const T key)
{
return SearchKey(mRoot, key);
}
BSTNode<T>* minKey()
{
return minKey(mRoot);
}
BSTNode<T>* maxKey()
{
return maxKey(mRoot);
}
// 插入节点
void insert( T key)
{
BSTNode<T> *z = new BSTNode<T>(key, NULL, NULL, NULL); if (z == NULL)
{
return;
}
insert(mRoot, z);
} private:
// 前序排序
void preOrder(BSTNode<T> *tree) const
{
if (tree != NULL)
{
cout << tree->key << " ";
preOrder(tree->left);
preOrder(tree->right);
}
} // 中序排序
void inOrder(BSTNode<T> *tree) const
{
if (tree != NULL)
{
preOrder(tree->left);
cout << tree->key << " ";
preOrder(tree->right);
}
} // 后序排序
void postOrder(BSTNode<T> *tree) const
{
if (tree != NULL)
{
preOrder(tree->left);
preOrder(tree->right);
cout << tree->key << " ";
}
}
BSTNode<T>* SearchKey(BSTNode<T>* pNode, const T key) const
{
// 递归查找
/*if (pNode = NULL || key == pNode->key)
{
return pNode;
}
else if (key > pNode->key)
{
return SearchKey(pNode->right);
}
else
{
return SearchKey(pNode->left);
}*/ // 非递归查找
BSTNode<T>* x = pNode;
while (x != NULL)
{
if (key > x->key)
{
x = x->right;
}
else if (key < x->key)
{
x = x->left;
}
else
{
return x;
}
} return NULL;
}
// 将节点插入到二叉树中
void insert(BSTNode<T>* &tree, BSTNode<T> *Node)
{
BSTNode<T> *y = NULL;
BSTNode<T> *x = tree;
while (NULL != x)
{
y = x;
if (Node->key > x->key)
{
x = x->right;
}
else
{
x = x->left;
}
} Node->parent = y; // 这到后面两句为关键代码
if (NULL == y)
{
tree = Node;
}
else if (Node->key > y->key)
{
y->right = Node;
}
else
{
y->left = Node;
}
}
// 查找最小节点
BSTNode<T>* minKey(BSTNode<T>* pNode) const
{
while (pNode != NULL)
{
pNode = pNode->left;
} return pNode;
}
BSTNode<T>* maxKey(BSTNode<T>* pNode) const
{
while (pNode != NULL)
{
pNode = pNode->right;
} return pNode;
}
// 找节点(x)的后继节点。即查找二叉树中数值大于该节点的最小值
BSTNode<T>* Successor(BSTNode<T>* x)
{
// 分三种情况
// 1. x有右孩子,找到以右孩子为根的子树的最小节点
// 2. x没有右孩子,当x为左孩子,则x的父节点为后继节点
// 2. x没有右孩子,当x为右孩子,则找x的最低父节点,并且该父节点具有左孩子
if (x->right != NULL)
{
return minKey(x->right);
}
BSTNode<T>* y = x->parent;
while ((NULL != y) &&(x == y->right))
{
x= y;
y = y->parent;
} return y;
}
// 找结点(x)的前驱结点。即查找"二叉树中数据值小于该结点"的"最大结点"
BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x)
{
// 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
if (x->left != NULL)
return maxKey(x->left); // 如果x没有左孩子。则x有以下两种可能:
// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
// (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
BSTNode<T>* y = x->parent;
while ((y!=NULL) && (x==y->left))
{
x = y;
y = y->parent;
} return y;
} // 删除二叉树中的节点,并返回被删除的节点
//BSTNode<T>* RemoveNode(BSTNode<T>* &tree, BSTNode<T>* pNode)
//{
// BSTNode<T>* x = tree; // while (NULL != x && pNode->key != x->key)
// {
// if (pNode->key > x->key)
// {
// x = x->right;
// }
// else if (pNode->key < x->key)
// {
// x = x->left;
// }
// } // // 找到或x为空 //}
};

二叉查找树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. 编写OC高质量的代码的有效方法

    1. 写这个只是为了自己记忆,有相关pdf文件,如需要留下邮箱.. 2. 在类的头文件中尽量少引入其他头文件 除非确有必要,否则不要引入头文件.一般来说,应在某个类的头文件中使用向前声明来提及别的类( ...

  2. sync_binlog innodb_flush_log_at_trx_commit 浅析

    一 参数意义 innodb_flush_log_at_trx_commit 如果innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log fil ...

  3. SQLServer 创建服务器和数据库级别审计

    概述 在上一篇文章中已经介绍了审计的概念:本篇文章主要介绍如何创建审计,以及该收集哪些审核规范. 一.常用的审核对象 1.1.服务器审核对象 1.FAILED_LOGIN_GROUP( Audit L ...

  4. flexbox 弹性盒子

    flexbox 弹性盒子 1.基本知识 container(容器)属性 flex-direction: row | row-reverse | column | column-reverse 属性决定 ...

  5. HDU2504-又见GCD-递归

    又见GCD Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. JAVA虚拟机之对象探秘

    上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...

  7. 在.Net中将RocketMQ跑起来_入门篇【2】

    上一篇讲了如何再控制台将RocketMQ跑起来,本篇讲解,在asp.net mvc种跑起来,含(发布.订阅). 本次将不挨个贴源码,直接展示目录,根据上一篇文章,进行相应的调整即可. 1.新建一个类库 ...

  8. Python 之 基础知识(三)

    一.函数 def 函数名(): 函数封装的代码 ... def是英文define缩写 别的Python文件可以引入 调用 定义时 和其他代码包括注释保留两个空行 pycharm 调试时 F8 Step ...

  9. MVC编程实例----简易电子商务网站(一)

    一.总体概览.规划 本文将会创建一个基本的电子商务网站.由于电子商务网站的基本功能都是差不多的,此处省去了需求分析等工作,直接总结出结论.分为4个基本功能: 商品浏览 会员功能 购物车 订单结账 其中 ...

  10. Dedecms列表页标签list/pagelist使用方法及pagelist的样式

    Dede的默认页面中有个list_article.htm页面,这是dede的列表页面.在列表页显示文章的列表,是通过dede的list和pagelist这两个个标签实现的.本文就这两个标签的使用及pa ...