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

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

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

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. WPF:行列显示

    新建显示病人信息控件PatientElement Add-->NewItem-->WPF-->UserControl(WPF),名称:PatientElement.xmal < ...

  2. translatesAutoresizingMaskIntoConstraints

    如果是从代码层面开始使用Autolayout,需要对使用的View的translatesAutoresizingMaskIntoConstraints的属性设置为NO,即可开始通过代码添加Constr ...

  3. 聚类算法:K-means 算法(k均值算法)

    k-means算法:      第一步:选$K$个初始聚类中心,$z_1(1),z_2(1),\cdots,z_k(1)$,其中括号内的序号为寻找聚类中心的迭代运算的次序号. 聚类中心的向量值可任意设 ...

  4. java网络编程serversocket

    转载:http://www.blogjava.net/landon/archive/2013/07/24/401911.html Java网络编程精解笔记3:ServerSocket详解ServerS ...

  5. [转]Java程序员们最常犯的10个错误

    1.将数组转化为列表 将数组转化为一个列表时,程序员们经常这样做: List<String> list = Arrays.asList(arr); Arrays.asList()会返回一个 ...

  6. bzoj 2324: [ZJOI2011]营救皮卡丘

    #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu ...

  7. LA 4123 - Glenbow Museum

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  8. 11个Linux基础面试问题

    Q.1: Linux 操作系统的核心是什么? Shell Kernel Command Script Terminal 答: 内核(Kernel)是Linux 操作系统的核心.Shell是一个命令行解 ...

  9. iOS-生成国际化包-配置App多语言支持

      标签: ios国际化 ios多语言支持 xcode多语言支持 xcode生成多语言 国际化 it 分类: 功能知识   如果你的App需要支持多国语言.那么,就应该为你的App应用添加“国际化”支 ...

  10. RPI学习--WebCam_mplayer

    1,安装mplayer $ sudo apt-get install mplayer 2,运行 $ sudo mplayer tv:// 有时会秀逗,绿屏,多试几下就好了,情况未知