二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树BinarySort Tree)或者是一棵空树,或者是具有下列性质的二叉树:

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

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

(3)它的左、右子树也分别为二叉查找树。

下面是它的几个重要函数:

插入结点:

【思路1】递归

终止条件(1,2):

1.若插入到一个空树中,则新建结点为根结点,左右孩子置为空,返回true

2.若等于根结点的值,返回false

3.若当前值小于根结点的值,递归左子树,否则递归右子树

  1. template<class T>
  2. bool BinarySearchTree<T>::InsertNode(BinaryTreeNode<T> * &root, T newpointer)
  3. {
  4. if (root == NULL)
  5. {
  6. root = new BinaryTreeNode<T>;
  7. root->element = newpointer;
  8. root->LeftChild = root->RightChild = NULL;
  9. return true;
  10. }
  11. if (newpointer == root->element)
  12. return false;
  13. if (newpointer < root->element)
  14. return InsertNode(root->LeftChild, newpointer);
  15. else
  16. return InsertNode(root->RightChild, newpointer);
  17. }

【思路2】非递归

1.若二叉树为空,则首先单独生成根结点

2.执行查找算法,找出被插结点的父亲结点

3.判断被插结点是其父亲结点的左、右儿子,并将被插结点作为叶子结点插入

注:新插入的结点总是叶子结点

  1. template<class T>
  2. bool BinarySearchTree<T>::InsertNode(BinaryTreeNode<T> * &root, T newpointer)
  3. {
  4. if (root == NULL)
  5. {
  6. root = new BinaryTreeNode<T>;
  7. root->element = newpointer;
  8. root->LeftChild = root->RightChild = NULL;
  9. return true;
  10. }
  11. BinaryTreeNode<T> *pointer = root;
  12. while(pointer != NULL)
  13. {
  14. if (newpointer == pointer->element)
  15. return false;
  16. else if (newpointer < pointer->element)
  17. {
  18. if(pointer->LeftChild == NULL)
  19. {
  20. BinaryTreeNode<T>* l = new BinaryTreeNode<T>(newpointer);
  21. l->LeftChild = l->RightChild = NULL;
  22. pointer->LeftChild = l;
  23. return true;
  24. }
  25. pointer = pointer->LeftChild;
  26. }
  27. else
  28. {
  29. if(pointer->RightChild == NULL)
  30. {
  31. BinaryTreeNode<T>* r = new BinaryTreeNode<T>(newpointer);
  32. r->LeftChild = r->RightChild = NULL;
  33. pointer->RightChild = r;
  34. return true;
  35. }
  36. pointer = pointer->RightChild;
  37. }
  38. }
  39. }

删除结点:

【思路】删除二叉搜索树中结点要根据删除的位置分情况讨论

1.删除叶子结点

操作:直接删除,更改它的父亲结点的相应指针场为空。

2.删除结点只有左儿子或只有右儿子

操作:将该结点的子树直接接到该结点位置

3.删除结点有两个子结点

(1)合并删除

(2)通过复制进行删除

选取替身(左子树中最大的结点或右子树中最小的结点)替换到删除结点的位置

  1. template<class T>
  2. void BinarySearchTree<T>::deleteBinarySearchTree(BinaryTreeNode<T>* root, T x)
  3. {
  4. bool find = false;
  5. int flag = ;//标志要删除的结点是前驱结点pre的左孩子还是右孩子
  6. BinaryTreeNode<T> *pre = NULL;
  7. while (root && !find)
  8. {
  9. if (x == root->element)
  10. {
  11. find = true;
  12. }
  13. else if (x < root->element)
  14. {
  15. pre = root;
  16. root = root->LeftChild;
  17. flag = -;
  18. }
  19. else
  20. {
  21. pre = root;
  22. root = root->RightChild;
  23. flag = ;
  24. }
  25. }
  26. if (root == NULL)
  27. {
  28. cout << "未找到要删除元素" << endl;
  29. return;
  30. }
  31. //此时root为要删除结点
  32.  
  33. //要删除结点是叶子结点
  34. if (root->isLeaf())
  35. {
  36. if (flag == )
  37. {
  38. delete root;
  39. root = NULL;
  40. }
  41. else if (flag == -)
  42. {
  43. pre->LeftChild = NULL;
  44. delete root;
  45. root = NULL;
  46. }
  47. else
  48. {
  49. pre->RightChild = NULL;
  50. delete root;
  51. root = NULL;
  52. }
  53. }
  54.  
  55. //要删除结点具有左右子结点
  56. else if (root->LeftChild && root->RightChild)
  57. {
  58. //复制删除,选取左子树中最大的结点替换
  59. BinaryTreeNode<T> *t = root;
  60. BinaryTreeNode<T> *s = root->LeftChild;
  61. while (s->RightChild)
  62. {
  63. t = s;
  64. s = s->RightChild;
  65. }
  66. root->element = s->element;
  67.  
  68. //此时S只有左孩子,需要连接到它的前驱结点t上
  69. if (root == t)//while循环未执行
  70. {
  71. t->LeftChild = s->LeftChild;
  72. }
  73. else//while循环已执行
  74. {
  75. t->RightChild = s->LeftChild;
  76. }
  77. delete s;
  78. s = NULL;
  79. }
  80.  
  81. else//要删除结点为单支子树根结点
  82. {
  83. if (flag == )//root为根结点
  84. {
  85. if (root->LeftChild)
  86. {
  87. pre = root;
  88. root = root->LeftChild;
  89. delete pre;
  90. pre = NULL;
  91. }
  92. else
  93. {
  94. pre = root;
  95. root = root->RightChild;
  96. delete pre;
  97. pre = NULL;
  98. }
  99. }
  100. else if (flag == -)//root为pre的左子树
  101. {
  102. if (root->LeftChild)//要删除结点只存在左子树
  103. {
  104. pre->LeftChild = root->LeftChild;
  105. delete root;
  106. root = NULL;
  107. }
  108. else//要删除结点只存在右子树
  109. {
  110. pre->LeftChild = root->RightChild;
  111. delete root;
  112. root = NULL;
  113. }
  114. }
  115. else//root为pre的右子树
  116. {
  117. if (root->LeftChild)//要删除结点只存在左子树
  118. {
  119. pre->RightChild = root->LeftChild;
  120. delete root;
  121. root = NULL;
  122. }
  123. else//要删除结点只存在右子树
  124. {
  125. pre->RightChild = root->RightChild;
  126. delete root;
  127. root = NULL;
  128. }
  129. }
  130. }
  131. }

查找结点:

【思路】分割式查找法:

1.若根结点的关键码等于查找的关键码,成功。

2.否则,若小于根结点的关键码,查其左子树;大于根结点的关键码,查其右子树。

二叉搜索树的高效率在于继续检索时只需查找两棵子树之一。

  1. template<class T>
  2. BinaryTreeNode<T>* BinarySearchTree<T>::Search(BinaryTreeNode<T>* root, T x)
  3. {
  4. BinaryTreeNode<T>* current = root;
  5. while((NULL != current) && (x != current->element))
  6. {
  7. if(x < current->element)
  8. current = Search(root->LeftChild,x);
  9. else
  10. current = Search(root->RightChild,x);
  11. }
  12. return current;
  13. }

[BinaryTree] 二叉搜索树(二叉查找树、二叉排序树)的更多相关文章

  1. 《数据结构与算法分析——C语言描述》ADT实现(NO.03) : 二叉搜索树/二叉查找树(Binary Search Tree)

    二叉搜索树(Binary Search Tree),又名二叉查找树.二叉排序树,是一种简单的二叉树.它的特点是每一个结点的左(右)子树各结点的元素一定小于(大于)该结点的元素.将该树用于查找时,由于二 ...

  2. 判断一棵树是否为二叉搜索树(二叉排序树) python

    输入一棵树,判断这棵树是否为二叉搜索树.首先要知道什么是排序二叉树,二叉排序树是这样定义的,二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的 ...

  3. 二叉搜索树 & 二叉树 & 遍历方法

    二叉搜索树 & 二叉树 & 遍历方法 二叉搜索树 BST / binary search tree https://en.wikipedia.org/wiki/Binary_searc ...

  4. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  5. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  6. OBST(Optimal Binary Tree最优二叉搜索树)

    二叉搜索树 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的 ...

  7. &12 二叉搜索树

    #1,定义 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的 ...

  8. 《剑指offer》— JavaScript(23)二叉搜索树的后序遍历序列

    二叉搜索树的后序遍历序列 题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 相关知识 二叉查找树(B ...

  9. 剑指Offer——二叉搜索树的后序遍历序列

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 分析: 二叉查找树(Binary Search ...

随机推荐

  1. oracle12c管理作业资源的一种方式

    数据库:12.1.0.2,rac,cdb模式 笔者负责移动两个12.1.0.2的cdb集群,一个在aix上,一个在linux上,不幸的是,它们都是混合型,数据有100多T. 由于其它部门交付的时候,已 ...

  2. centos7中vsftp的搭建

    开启vsftpd:service vsftpd start关闭vsftp:service vsftpd stop 安装vsftpd: yum -y install vsftpd 建立vsftpd帐号: ...

  3. 构造HTTP请求Header实现“伪造来源IP”

    在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无 ...

  4. Scala语法(二)

    (1)类,对象 //定义类(属性.方法),实例化对象 class counter{ *//主构造器 class counter(name:String,mode:Int){ ... } 实例化:val ...

  5. docker配置与实践#可以好好看看

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源.Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 L ...

  6. php安装php-redis扩展

    下载安装php-redis扩展: 地址:https://github.com/phpredis/phpredis/ $ wget http://pecl.php.net/get/redis-3.1.2 ...

  7. python网络编程的坑(持续更新)

    初学python,踩了许多坑...每天都学一点吧..(大佬绕过) 1.session的用法: session是python requests库中的一个重要功能.session可以存储用户的数据并且存储 ...

  8. ffplay使用笔记

    ffplay播放yuv文件命令: ffplay -f rawvideo -video_size 1920x1080 a.yuv   ffplay播放mp4.h.264.hevc文件命令: ffplay ...

  9. sudo mount -o loop pm.img /mnt/floppy

    sudo mount -o loop pm.img /mnt/floppy 最近在学<一个操作系统的实现>,由于这本书比较老了,所以有一些对于软盘的操作指令现在用会出现一些错误,当我进行虚 ...

  10. 修改mysql root密码的方法

    方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...