动态管理集合的数据结构——二叉搜索树

搜索树是一种可以进行插入,搜索,删除等操作的数据结构,可以用字典或者优先队列

二叉排序树又称为二叉查找树,他或者为空树,或者是满足如下性质的二叉树。

(1)若它的左子树非空,则左子树上所有结点的值均小于根结点的值。

(2)若它的右子树非空,则右子树上所有结点的值均大于根结点的值。

(3)它的左、右子树本身又各是一棵二叉排序树。

对于二叉排序树进行中序遍历可以得到按结点值递增排序的结点序列。

--------------------------------------------------------------------------------------

二叉排序树用的头文件

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef struct node
{int data;node *lchild,*rchild;
}bsnode;

--------------------------------------------------------------------------------------

一、二叉搜索树——插入

假设待插入的数据元素是x。

1.1第一种情况

root为空,直接插入,让它成为根结点。

1.2第二种情况

要插入的元素已经存在,则无需插入。

1.3第三种情况

若x小于根结点的关键字,则将该结点插入该树的左子树中,否则则将该结点插入该树的右子树中。

伪代码:

 insert(T, z)y = NIL // parent of xx = 'the root of T'while x ≠ NILy = x // set the parentif z.key < x.keyx = x.left // move to the left childelse x = x.right // move to the right childz.p = yif y == NIL // T is empty'the root of T' = zelse if z.key < y.keyy.left = z // z is the left child of yelse y.right = z // z is the right child of y

现学现用

1、Binary Search Tree I

https://vjudge.net/problem/Aizu-ALDS1_8_A

#include <iostream>
#include <string>
using namespace std;typedef struct node
{int num;node *lchild,*rchild;node(){num=0;lchild = NULL;rchild = NULL;}
}N;N *root;void insert(int x)
{if(root == NULL){root = new N;root->num = x;return ;}N *p = root,*par;while(p!=NULL){if(p->num == x)return ;if(p->num > x)//进入左子树 {par = p;p = p->lchild;}else //进入右子树 {par = p;p = p->rchild;}}if(par->num > x){par->lchild = new N;par = par->lchild; par->num = x;}else{par->rchild = new N;par = par->rchild;par->num = x;}return ;
}void preorder(N* t)
{if(t){cout <<" "<<t->num;preorder(t->lchild);preorder(t->rchild);}
}void inorder(N *t)
{if(t){inorder(t->lchild);cout << " " << t->num ;inorder(t->rchild);}
}int main()
{int n;cin >> n;string s;int x; root = NULL;while(n--){cin >> s;if(s == "print"){inorder(root);cout << endl;preorder(root);cout << endl; }else if(s=="insert"){cin >> x;insert(x);}}return 0;
} 

二、二叉搜索树——查找

对于一棵给定的二叉排序树,树中的查找运算很容易实现。

(1)当一棵二叉树为空树时,检索失败。

(2)如果一棵二叉排序树的根结点的关键字等于待检索的关键字,则检索成功。

(3)如果二叉排序树的根结点的关键字小于待检索的关键字,则用相同的方法继续在根结点的右子树中检索。

(4)如果二叉排序树的根结点的关键字大于待检索的关键字,则用相同的方法继续在根结点的左子树中检索。

现学现用

1、Binary Search Tree II

https://vjudge.net/problem/Aizu-ALDS1_8_B

和上面那道例题一样,只是多了一个find功能

bool find(int x)
{N *p = root;while(p!=NULL){if(p->num==x)return true;if(x>p->num)p=p->rchild;elsep=p->lchild;}return false;
}

三、二叉搜索树——删除

与在二叉排序树上进行插入操作的要求一样,从二叉排序树中删除一个结点,要保证删除后的二叉树仍然是一棵二叉排序树。

删除结点z

(1)待删除的结点为叶子结点。直接删除该结点。

(2)待删除的结点只有左子树,而无右子树。那么就让该节点的父亲结点指向该节点的左孩子,然后删除该节点。

(3)待删除的结点只有右子树,而无左子树。那么就让该节点的父亲结点指向该节点的右孩子,然后删除该节点。

(4)待删除结点既有左子树,又有右子树。

找到该结点的右子树中的最左孩子,也就是右子树中序遍历的第一个结点。把它的值和要删的结点的值进行交换,然后删除这个节点即相当于把我们想删除的节点删除了。

void del(int x)
{N *p = root,*par;while(p->num!=x){if(p->num>x){par = p;p=p->lchild;            }else {par = p;p=p->rchild;}}if(p->lchild==NULL && p->rchild==NULL){if(par->lchild==p)par->lchild=NULL;else if(par->rchild==p)par->rchild=NULL;delete p;return ;}if(p->lchild!=NULL && p->rchild==NULL)//只有左孩子 {if(p==root)root = p->lchild;else if(par->lchild ==p)par->lchild = p->lchild;else if(par->rchild == p)par->rchild = p->lchild;delete p;return ;}else if(p->lchild==NULL && p->rchild!=NULL)//只有右孩子 {if(p==root)root = p->rchild;else if(par->lchild==p)par->lchild = p->rchild;else if(par->rchild==p)par->rchild = p->rchild;delete p;return ;}else if(p->lchild!=NULL && p->rchild!=NULL)//既有左孩子,又有右孩子 {// 找到右子树中序遍历的最左结点。N *left=p->rchild;//left为右子树的根结点。 par = p;while(left->lchild){par = left;left = left->lchild;} //交换结点的值 p->num = left->num;if(par->lchild==left)par->lchild = left->rchild; else if(par->rchild==left)par->rchild = left->rchild;delete left;return ;}
}

现学现用

1、HDU-3791

https://vjudge.net/problem/HDU-3791

  

首先创建二叉搜索树,然后按照前序遍历的方式判断

#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;typedef struct node
{char num;node *lchild,*rchild;node(){num='0';lchild = NULL;rchild = NULL;}
}N;N *root;
int k;
int b[25],a[25];N *insert(char x,N *root)
{if(root == NULL){root = new N;root->num = x;return root;}N *p=root,*par;while(p!=NULL){if(p->num==x)return root;if(p->num>x){par = p;p = p->lchild;}else if(p->num < x){par = p;p = p->rchild;}    }if(par->num > x){par->lchild = new N;par = par->lchild;par->num  = x;}else if(par->num < x){par->rchild = new N;par = par->rchild;par->num = x;}return root;
}void preorder(N *t)
{if(t){b[k++]=t->num;preorder(t->lchild);preorder(t->rchild);}
}int main()
{int T,i;k=0;char s[25];while(scanf("%d",&T)!=EOF && T){memset(b,-1,sizeof(b));memset(a,-1,sizeof(a));scanf("%s",s);root = NULL;for(i=0;s[i];i++){root = insert(s[i]-'0',root);}preorder(root);k=0;for(i=0;b[i]!=-1;i++)a[i]=b[i];while(T--){memset(b,-1,sizeof(b));scanf("%s",s);root = NULL;for(i=0;s[i];i++){root = insert(s[i]-'0',root);}preorder(root);int flag =1;for(i=0;b[i]!=-1;i++){if(a[i]!=b[i]){flag=0;break;}}if(flag)printf("YES\n");elseprintf("NO\n");k=0;}}return 0;
} 

2、Elven Postman

http://acm.hdu.edu.cn/showproblem.php?pid=5444

只输出“\n”,一开始还多输出了一个空格,直接PE

由于这棵树是倒着的,所以创建的时候需要注意,什么时候输出“W”什么时候输出“E”,别晕了

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;typedef struct node
{int num;node *rchild,*lchild;node(){num=-1;lchild = NULL;rchild = NULL;}
}N;N *insert(int x,N *root)
{if(root == NULL){root = new N;root->num  =x;return root; }N *p = root, *par;while(p!=NULL){if(p->num > x){par = p;p = p->rchild; }else if(p->num < x){par = p;p = p->lchild;}}if(par->num > x){par->rchild = new N;par = par->rchild;par->num = x;return root;}if(par->num < x){par->lchild = new N;par = par->lchild;par->num = x;return root;}
}void inorder(N *t)
{if(t){inorder(t->lchild);cout << t->num << " ";inorder(t->rchild);}
}void find(int x,N *root)
{if(x==root->num){return ;}    N *p = root;while(p->num!=x){if(p->num < x){cout << "W";p = p->lchild;}else{cout << "E";p = p->rchild;}}
}int main ()
{int T, n, room_num, t, mail_num;cin >> T;while(T--){cin >> n;N *root = NULL;while(n--){cin >> room_num;root = insert(room_num,root);}cin >> t;while(t--){cin >> mail_num;find(mail_num,root);cout << endl;}}return 0;
}

【ACM】二叉搜索树(Binary Search Tree /BS Tree) 小结相关推荐

  1. C++二叉搜索树(Binary Search Tree)(附完整源码)

    二叉搜索树Binary Search Tree node结构体定义 Queue结构体定义 二叉搜索树Binary Search Tree算法的完整源码(定义,实现,main函数测试) node结构体定 ...

  2. 实现一个二叉搜索树(Binary Search Tree)

    文章目录 定义 代码实现 一.Github代码地址 二.节点 三.树实现接口 四.4种遍历方式 五.搜索 六.删除 七.插入 结尾 定义 二叉搜索树(Binary Search Tree),又名二叉排 ...

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

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

  4. go 递归tree关系_Go实现一个二叉搜索树

    什么是二叉搜索树 二叉搜索树(binary search tree,BST[1])也叫排序的二叉树,根节点比左边子树的所有节点都大,比右边子树上的所有节点都小,如下图就是一个二叉搜索树: 要实现一个二 ...

  5. 数据结构之二叉搜索树(BST)

    数据结构之二叉搜索树(BST) 1. 二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: ( ...

  6. b+树时间复杂度_深入理解数据库系统之存储存引擎(二叉搜索树)

    B树是数据库存储引擎使用的最多的存储结构之一.许多开源数据库系统也都大量使B用树作为存储结构,多年来已经证明它们能够胜任大多数使用场景. 早在1971年鲁道夫·拜尔(Rudolph Bayer)和爱德 ...

  7. 数据结构与算法笔记(十六)—— 二叉搜索树

    一.二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: 若左子树不为空,则左子树上所有节点的 ...

  8. php实现二叉搜索树,二叉搜索树有几种实现方式

    二叉搜索树有一种实现方式,就是用链表实现,而链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,且链表是由一系列结点组成,结点可以在运行时动态生成. ...

  9. 数据结构——二叉搜索树

    一.定义 二叉搜索树(binary search tree),又叫二叉查找树.二叉排序树.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于 ...

  10. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

最新文章

  1. python(40):利用utf-8编码判断中文英文字符
  2. Python print函数不换行操作
  3. wxWidgets:wxSashWindow类用法
  4. 老板思维:有支出必须有对应的收入
  5. 怎么把文件放到docker容器里
  6. 100行Python代码实现一款高精度免费OCR工具
  7. 商户分账交易汇总和商户交易汇总不一致
  8. Linux 命令(117)—— gzip 命令
  9. ie下解决PNG图片不透明问题
  10. React Router的Route的使用
  11. Nginx漏洞扫描及修复
  12. 计算机关机的命令行,自动关机命令,windows自动关机命令
  13. 迅雷极速版任务出错的解决办法(亲测可用)
  14. linux如何从 命令行 将普通文件打印到 pdf
  15. UE源码版本下载编译全流程
  16. 计算机显示u盘隐藏分区,如何查看及删除u盘的隐藏分区
  17. GDC演讲翻译——看门狗2的载具同步
  18. ASP.NET MVC入门视频教程
  19. 从JPG和JPEG图片获取压缩比详细教程
  20. Python语言在人工智能(AI)中的优势

热门文章

  1. (C++)1020 月饼 简单贪心
  2. 学Java的软件哪些比较好用
  3. 【Python培训基础知识】Python生成器函数
  4. iOS FMDB之FMDatabaseQueue(事物与非事物)
  5. bc计算命令的知识及企业计算案例
  6. 新手安装ruby on rails(ror)的成功必备手册
  7. Androidstudio下Generate signed apk提示Error: Expected resource of type id [ResourceType]解决办法...
  8. C#强化系列文章四:匿名方法的使用
  9. Linux下查找nginx配置文件路径
  10. 中秋节,送上一次非常有趣的SQL优化实战经历