二叉树的一个重要应用就是查找。

二叉搜索树 满足如下的性质:

左子树的关键字 < 节点的关键字 < 右子树的关键字

1. Find(x)

有了上述的性质后,我们就可以像二分查找那样查找给定的关键字x

具体如下: if x < node->val, Search in left sub-tree;

else if x > node->val, Search in right sub-tree;

else, found it!

2. Insert(x)

插入操作像Find(x)一样非常简单。要保证插入后,树仍然保持 左子树<本身<右子树

那如何找到具体的插入位置呢? 我们可以换个思路考虑问题,假设x已经在树中,那它所在的位置就是插入位置!

Bingo! 上面的搜索算法得到的搜索路径的最后就是我们所求!

具体思路是:

按照Find的方法,搜索x, 如果发现已经有节点的值=x, 则返回;

否则, 在搜索路径的最后插入新的节点(x)

Figure 2: 插入关键字5

3. Delete(x)

删除操作相对麻烦一些。要考虑删除的节点有几个孩子。

首先搜索关键字x, 若没有,则返回。否则,删除该节点。

1> 若节点 has no child, 直接删除节点即可,能够保证所有节点满足 左子树<本身<右子树

2> 若节点 has one child,(不妨设为仅有右孩子)

3> 若 two children

为了保证搜索二叉树的性质,讲右子树中的最小值赋值给当前节点,然后递归删除右子树的最小节点

时间复杂度分析:

注意到上述的操作复杂度都是 O(h), h为树的高度。

因此如果二叉树是如下图的情况,二叉树将退化为链表,复杂度变为线性。

为了避免这种情况,在插入删除的时候引入平衡操作,保证树满足某一种平衡条件。这就是二叉平衡树。

// copyright @ L.J.SHOU Nov.8, 2013
// Binary Search Tree #include "search-tree.h"
#include "binary-tree-printer.h"
#include <cstdlib>
#include <queue>
#include <iostream>
using namespace std; const int N=10;
const int M=10;
typedef int ElementType; /*
struct TreeNode
{
ElementType val;
TreeNode* left;
TreeNode* right;
TreeNode(ElementType x)
: val(x), left(NULL), right(NULL){}
};
*/ TreeNode* Destroy(TreeNode *t)
{
if(t != NULL)
{
t->left = Destroy(t->left);
t->right = Destroy(t->right);
delete t;
} return NULL;
} int Height(TreeNode *t)
{
if(t == NULL)
return -1; int left = Height(t->left);
int right = Height(t->right); if(left > right)
return left + 1;
else
return right + 1;
} TreeNode* Find(TreeNode *t, ElementType x)
{
if(t != NULL)
{
if(x < t->val)
return Find(t->left, x);
else if(x > t->val)
return Find(t->right, x);
else
return t;
}
return NULL;
} TreeNode* FindMin(TreeNode *t)
{ // iterative
TreeNode* p = t; while(p && p->left)
p = p->left; return p;
} TreeNode* FindMax(TreeNode* t)
{ // recursive
if(t == NULL)
return NULL;
else if(t->right == NULL)
return t;
else
return FindMax(t->right);
} TreeNode* Insert(TreeNode* t, ElementType x)
{ // recursive
if(t == NULL)
{
t = new TreeNode;
t->val = x;
t->left = t->right = NULL;
}
else if(x < t->val)
t->left = Insert(t->left, x);
else if(x > t->val)
t->right = Insert(t->right, x);
/* else x is already in the tree;
we'll do nothing */
return t;
} TreeNode* Delete(TreeNode* t, ElementType x)
{ /* recursive */
TreeNode* p(NULL); if(t == NULL)
cerr << "Element " << x << " Not Found" << endl;
else{
if(x < t->val)
t->left = Delete(t->left, x);
else if(x > t->val)
t->right = Delete(t->right, x);
else
{ /* t->val = x */
if(t->left && t->right)
{ /* two children */
/* find min in the right sub-tree */
p = FindMin(t->right);
t->val = p->val;
t->right = Delete(t->right, t->val);
}
else
{ /* one or no child */
p = t;
if(t->left == NULL)
t = t->right;
else if(t->right == NULL)
t = t->left;
delete p;
}
}
}
return t;
} void PreOrderVisit(TreeNode* t)
{
if(t)
{
cout << t->val << " ";
PreOrderVisit(t->left);
PreOrderVisit(t->right);
}
} void InOrderVisit(TreeNode* t)
{
if(t)
{
InOrderVisit(t->left);
cout << t->val << " ";
InOrderVisit(t->right);
}
} void LevelOrderVisit(TreeNode* t)
{
if(t == NULL) return; TreeNode *node(NULL);
queue<TreeNode* > q;
q.push(t); while(!q.empty())
{
node = q.front(); q.pop();
cout << node->val << " ";
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
}
} int main()
{
TreeNode* t(NULL); srand(time(0));
for(int i=0; i<N; ++i)
t = Insert(t, rand()%M+1); cout << "PreOrder: ";
PreOrderVisit(t);
cout << endl; cout << "InOrder: ";
InOrderVisit(t);
cout << endl; cout << "LevelOrder: ";
LevelOrderVisit(t);
cout << endl; cout << "Height: " << Height(t) << endl;
cout << "Min: " << FindMin(t)->val << endl;
cout << "Max: " << FindMax(t)->val << endl; PrintBinaryTree(t);
t = Destroy(t);
return 0;
}

数据结构 《5》----二叉搜索树 ( Binary Search Tree )的更多相关文章

  1. 编程算法 - 二叉搜索树(binary search tree) 代码(C)

    二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...

  2. [Data Structure] 二叉搜索树(Binary Search Tree) - 笔记

    1. 二叉搜索树,可以用作字典,或者优先队列. 2. 根节点 root 是树结构里面唯一一个其父节点为空的节点. 3. 二叉树搜索树的属性: 假设 x 是二叉搜索树的一个节点.如果 y 是 x 左子树 ...

  3. 二叉搜索树(Binary Search Tree)(Java实现)

    @ 目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  4. 二叉搜索树(Binary Search Tree)实现及测试

    转:http://blog.csdn.net/a19881029/article/details/24379339 实现代码:  Node.java  //节点类public class Node{ ...

  5. 【算法与数据结构】二叉搜索树的Java实现

    为了更加深入了解二叉搜索树,博主自己用Java写了个二叉搜索树,有兴趣的同学可以一起探讨探讨. 首先,二叉搜索树是啥?它有什么用呢? 二叉搜索树, 也称二叉排序树,它的每个节点的数据结构为1个父节点指 ...

  6. 用Python实现数据结构之二叉搜索树

    二叉搜索树 二叉搜索树是一种特殊的二叉树,它的特点是: 对于任意一个节点p,存储在p的左子树的中的所有节点中的值都小于p中的值 对于任意一个节点p,存储在p的右子树的中的所有节点中的值都大于p中的值 ...

  7. hdu 3791:二叉搜索树(数据结构,二叉搜索树 BST)

    二叉搜索树 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submiss ...

  8. 数据结构之二叉搜索树、AVL自平衡树

    前言 最近在帮公司校招~~ 所以来整理一些数据结构方面的知识,这些知识呢,光看一遍理解还是很浅的,看过跟动手做过一遍的同学还是很容易分辨的哟~ 一直觉得数据结构跟算法,就好比金庸小说里的<九阳神 ...

  9. 数据结构之二叉搜索树(BST)--JavaScript实现

    原理: 叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构.中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程 ...

随机推荐

  1. vs版本的改变处理

    今天要用VS2010打开VS2013,一直觉得VS2010到VS2012只是界面上扁平化的改变,平台工具集有改变但很大程度上可能向上兼容.在网上搜了一些文章,其中有一篇说到一个观点:        从 ...

  2. (14)odoo加载机制

    Odoo的启动通过openerp-server脚本完成,它是系统的入口. 然后加载配置文件openerp-server.conf 或者 .openerp_serverrc: openerp-serve ...

  3. (11)odoo权限机制

    -----------------更新时间:10:21 2016-09-29 星期四14:31 2016-09-28 星期三 权限对象命名修改18:06 2016-09-18 星期日11:55 201 ...

  4. (02)odoo自定义模块

    * 官方建议模块骨架    --------------------------    addons/<my_module_name>/                 │─ __init ...

  5. OC 实例变量(Instance Var)和成员变量(member var)区别

    摘要:  Objective-C  引入了“实例变量"的概念,但同时, 也经常出现 “成员变量”的声音. 到底什么是实例变量,什么是成员变量,二者的区别是什么呢? 今天查看apple 的官方 ...

  6. Java 集合系列 05 Vector详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  7. 让Windows下的Tomcat将控制台信息记录到日志

    在开发的过程中经常出现包冲突,却不知道怎么回事,可以在 catalina.bat 里面设置查看class加载日志   set CATALINA_OPTS=-server -Xdebug -Xnoage ...

  8. Octopus系列之关于多选属性如何在OO中表示呢?

    在电子商务系统中 关于产品属性的问题 会设计如下几个表 产品信息        Product 选项信息表     Option        存储 Size  Color.... 选项值信息表  O ...

  9. eclipse关联tomcat并且部署java web应用程序

    http://www.ibm.com/developerworks/cn/opensource/os-eclipse-tomcat/

  10. 模拟QQ侧滑控件 实现三种界面切换效果(知识点:回调机制,解析网络json数据,fragment用法等)。

    需要用到的lib包 :解析json  gson包,从网络地址解析json数据成String字符串的异步网络解析工具AsyncHttpClient等 下载地址:点击下载 Xlistview 下拉上拉第三 ...