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

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

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

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. ccs6.0使用问题记录

    ccs6.0使用问题记录 彭会锋 1 编译过程中提示warning  " Description Resource Path Location Type #9-D nested commen ...

  2. DSP算法学习-过采样技术

    DSP算法学习-过采样技术 彭会锋 2015-04-27 23:23:47 参考论文: 1 http://wr.lib.tsinghua.edu.cn/sites/default/files/1207 ...

  3. 数据库中Schema(模式)概念的理解

    在学习SQL的过程中,会遇到一个让你迷糊的Schema的概念.实际上,schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不 ...

  4. IntelliJ IDEA 12 与 Tomcat 集成并运行Web项目

    配置Tomcat Server 1.Ctrl+Alt+s或者File——>Setting...;选中“Application Servers”点击"+" 创建运行配置 上面的 ...

  5. 转:Struts2<s:iterator value="" var="lst">中var的使用和一些标签的使用体会

    比如<s:iterator value="pmOperateList" var="lst"> <!-- iterator加上var 等价于重新 ...

  6. GPOR

    [tengzhenzhen15@lu01 gpor]$ for ((i=0; i<=19; i++)) do ./gpor -S 0.4 X4058_300_gpor/mytask_train. ...

  7. 高度30px,宽度自适应,点线在文字中间

    <style>  .div{ position: relative; width: 100%; height: 30px; background: #ffff00}        .div ...

  8. NodeJS无所不能:细数10个令人惊讶的NodeJS开源项目

    在几年的时间里,NodeJS逐渐发展成一个成熟的开发平台,吸引了许多开发者.有许多大型高流量网站都采用NodeJS进行开发,像PayPal,此外,开发人员还可以使用它来开发一些快速移动Web框架. 除 ...

  9. spring项目中使用定时任务

    当我们希望在某个时间点来执行一些业务方法的时候就用到定时任务,在spring的项目中使用定时任务很简单.如下 第一步.加入jar包 <dependency> <groupId> ...

  10. 修改weblogic部署的应用名称

    通过weblogic管理后台console进行发布本地项目的时候,它会默认以WEB-INF的上一级目录作为访问路径,如,假如你的项目WEB-INF目录的上一层是WebRoot,那么发布后,访问的路径默 ...