定义

排序二叉树的定义也是递归定义的,需要满足:

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

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

(3)左、右子树也分别是排序二叉树

如下图,对于排序二叉树,若按中序遍历就可以得到由小到大的有序序列。

创建

创建排序二叉树的步骤就是不断像排序二叉树中添加新节点(p)的过程:

(1)以根节点(root)为当前节点(current)开始搜索;

(2)用新节点p的值和current的值进行比较;

(3)如果p.data>current.data,则current=current.right;若p.data<current.data,则current=current.left;

(4)重复(2)(3),直到找到合适的叶子节点位置;

(5)将p添加到上面找到的合适位置,若新节点更大,则添加为右子节点;否则,加为左子节点

删除节点

当从排序二叉树中删除节点后,要保持它依然是二叉树,必须对它进行维护:

待删除节点p,p的父节点q,p的左子树pL,p的右子树pR

(1·)p是叶子节点,直接将它从其父节点中删除;

(2)p只有左(右)子树,将pL(pR)添加成p的父节点q的左(右)子树即可;

(3)p左右子树均非空,有两种处理方法:

  • 将pL设为q的左或右子节点(取决于p是其父节点q的左、右子节点),将pR设为p的中序前驱结点s的右子节点(s是pL最右下的节点,也就是pL中最大的节点)
  • 以p的中序前驱或后继替代p所指节点,然后再从原排序二叉树中删去中序前驱或后继节点(也就是用大于p的最小节点或小于p的最大节点代替p节点)

Java实现代码:

package com.liuhao.DataStructures;import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;public class SortedBinTree <T extends Comparable>{static class Node{Object data;Node parent;Node left;Node right;public Node(Object data, Node parent, Node left, Node right) {this.data = data;this.parent = parent;this.left = left;this.right = right;}public String toString(){return "[data=" + data + "]";}public boolean equals(Object obj){if(this == obj){return true;}if(obj.getClass() == Node.class){Node target = (Node) obj;return data.equals(target.data) && left == target.left && right == target.right && parent == target.parent;}return false;}}private Node root;public SortedBinTree(){root = null;} public SortedBinTree(T o){root = new Node(o, null, null, null);}/*** 添加节点* @param ele 新节点的元素*/public void add(T ele){if(root == null){root = new Node(ele, null, null, null);}else{Node current = root;Node parent = null;int cmp;//搜索合适的叶子节点,以该叶子节点为父节点添加新节点do{parent = current;cmp = ele.compareTo(current.data);//如果新节点的值大于当前节点的值if(cmp > 0){//以当前节点的右子节点作为当前节点current = current.right;}else{current = current.left;}}while(current != null);//创建新节点Node newNode = new Node(ele, parent, null, null);//如果新节点的值大于父节点的值if(cmp > 0){parent.right = newNode;}else{parent.left = newNode;}}}/*** 删除节点* @param ele*/public void remove(T ele){Node target = getNode(ele);if(target == null){return;}//左右子树都为空if(target.left == null && target.right == null){if(target == root){root = null;}else{//被删除节点是父节点的左子节点if(target == target.parent.left){//将target的父节点的left设为nulltarget.parent.left = null;}else{target.parent.right = null;}target.parent = null;}}//左空右不空else if(target.left == null && target.right != null){if(target == root){root = target.right;}else{//被删除节点是父节点的左子节点if(target == target.parent.left){target.parent.left = target.right;}else{target.parent.right = target.right;}//让target的右子树的parent指向target的parenttarget.right.parent = target.parent;}}else if(target.left != null && target.right == null){if(target == root){root = target.left;}else{//被删除节点是父节点的左子节点if(target == target.parent.left){target.parent.left = target.left;}else{target.parent.right = target.left;}//让target的右子树的parent指向target的parenttarget.left.parent = target.parent;}}//左右都不为空else{//leftMaxNode:target的左子树中值最大的节点Node leftMaxNode = target.left;//搜索target的左子树中值最大的节点while(leftMaxNode.right != null){leftMaxNode = leftMaxNode.right;}//从原来的子树中删除leftMaxNode节点leftMaxNode.parent.right = null;leftMaxNode.parent = target.parent;if(target == target.parent.left){target.parent.left = leftMaxNode;}else{target.parent.right = leftMaxNode;}leftMaxNode.left = target.left;leftMaxNode.right = target.right;target.parent = target.left = target.right = null;}}/*** 根据指定值搜索节点* @param ele 指定值* @return 节点*/public Node getNode(T ele){//从根节点开始搜索Node p = root;while(p != null){int cmp = ele.compareTo(p.data);if(cmp < 0){p = p.left;}else if(cmp > 0){p = p.right;}else{return p;}}return null;}/*** 广度优先遍历* @return*/public List<Node> breadthFirst(){Queue<Node> queue = new ArrayDeque<Node>();List<Node> list = new ArrayList<Node>();if(root != null){queue.offer(root);}while(!queue.isEmpty()){//将该队列的“队尾”元素添加到List中list.add(queue.peek());//弹出队尾节点Node p = queue.poll();//如果左子节点不为null,将它加入“队列”if(p.left != null){queue.offer(p.left);}if(p.right != null){queue.offer(p.right);}}return list;}/*** 中序遍历* @return*/public List<Node> inIterator(){return inIterator(root);}private List<Node> inIterator(Node node){List<Node> list = new ArrayList<Node>();//递归处理左子树if(node.left != null){list.addAll(inIterator(node.left));}//处理根节点list.add(node);//递归处理右子树if(node.right != null){list.addAll(inIterator(node.right));}return list;}
}

您的关注是我坚持写作的动力,如果觉得有用,欢迎关注我的微信,海量学习资源免费送!

排序二叉树及其Java实现相关推荐

  1. 二叉树 排序二叉树-可以通过中序遍历得到排序的数据 二叉排序树时间复杂度O(logn),...

    二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 虽然二叉排序树的最坏效率是O(n),但它支持动 ...

  2. java代码实现排序二叉树

    创建排序二叉树的步骤: 1.以根节点为当前节点开始搜索 2.拿新节点的值和当前节点的值比较 3.如果新节点的值更大,则以当前结点的右子节点作为新的当前节点:如果新节点的值更小,则以当前节点的左子节点作 ...

  3. Java数据结构——排序二叉树

    排序二叉树概念 二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树.是数据结构中的一类. 对于二叉排序树的任何一个非叶子节点, 要求 ...

  4. Java数据结构学习——排序二叉树

    目录 前言 正文 排序二叉树的特点 插入节点 删除树节点 删除的节点是叶子节点 删除的节点存在左或者右子节点 删除的节点存在左右两子节点 遍历节点 先序遍历 中序遍历 后续遍历 全部代码展示 总结 前 ...

  5. 一步一图一代码之排序二叉树

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong/) 属性: ①若它的左子树不为空,则左子树上所有节点的值均小于它的根节点的值. ②若它的右子树不为空,则右子树上所 ...

  6. java 二叉树特点_二叉树的Java实现及特点总结

    二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 我们先介绍一些关于二叉树的概念名词. 二叉树: ...

  7. 内部排序比较(Java版)

    内部排序比较(Java版) 2017-06-21 目录 1 三种基本排序算法 1.1 插入排序 1.2 交换排序(冒泡) 1.3 选择排序(简单) 2 比较 3 补充 3.1 快速排序 3.2 什么是 ...

  8. 排序二叉树(概念性)了解一下

    文章目录 基本概念 基本算法 1.查找 2.遍历 3.插入 4.删除 平衡的排序二叉树 参考文章 基本概念 树的基本概念,在计算机程序中,树是从上往下长的,也会有分叉,有个根节点,每个节点可以有一个或 ...

  9. 排序二叉树,平衡二叉树和红黑树的概念以及相关的操作讲解

    1. 排序二叉树 排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索. 排序二叉树要么是一棵空二叉树,要么是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均 ...

最新文章

  1. 机器学习可解释性工具箱XAI
  2. 如何列出Git 1.7+中的所有远程分支?
  3. DayDayUp:三观一致必将取代血缘关系,成为新的人际纽带(博主推荐文章)
  4. 成功解决RuntimeWarning: invalid value encountered in double_scalars
  5. 数据库-数据库设计-5个
  6. 为什么Android Geeks购买Nexus设备
  7. jmeter进行性能测试_使用JMeter进行性能测试
  8. 网站架构探索(1)---序言
  9. Flume1.5.0的安装、部署、简单应用(含伪分布式、与hadoop2.2.0、hbase0.96的案例)
  10. java 不能用 random,关于Java中Random的一些使用细节
  11. Python两种方法求解登楼梯问题(京东2016笔试题)
  12. C程序设计语言现代方法17:指针的高级应用
  13. Fixchart图表组件——介绍
  14. iOS中控制器的实践和学习(2)-认识XCode4模版(A1,A3,B2简易图)
  15. mysql添加一个字段(
  16. android碎片按钮,Android 碎片学习 之 如何在碎片调用Activity中的方法来进行赋值操作...
  17. oracle建表创建约束
  18. raft-rs 示例程序源码解读
  19. django 过滤器 、日期格式化参数
  20. eclipse 背景绿豆沙颜色

热门文章

  1. RTL乒乓运算模块设计 - Submodule Design
  2. 体验提升1:提升用户体验,应该从哪里开始?
  3. Python网络爬虫:利用正则表达式爬取豆瓣电影top250排行前10页电影信息
  4. JAVA实现余弦相似度算法
  5. 小辣椒android密码怎样开,小辣椒i2刷机方法指南(图文详解)
  6. 【前缀和】B014_LQ_k倍区间(烂公式转换)
  7. Webpack(干货嗷)
  8. 生肖派对怎么放机器人_香肠派对空投机甲在哪 空投机甲获取攻略[多图]
  9. 一起来捉妖服务器维护时间,一起来捉妖2月21日终极测试 测试时间与玩法更新一览...
  10. 前端必须知道——设计模式六大原则