二分查找树

public class BinarySearchTree {private Node root;//查找结点public Node search(int data) {Node targetNode = root;while (targetNode!=null && targetNode.data != data) {if (data > targetNode.data) {targetNode = targetNode.right;} else {targetNode = targetNode.left;}}if(targetNode == null){System.out.println("未找到结点:" + data);} else {System.out.println("已找到结点:" + data);}return targetNode;}//中序遍历public static void inOrderTraversal(Node node){if(node == null){return;}inOrderTraversal(node.left);System.out.print(node.data + " ");inOrderTraversal(node.right);}//插入结点public boolean insert(int data) {Node node = new Node(data);if(root == null){root = node;return true;}Node targetNode  = root;while (targetNode != null) {if( data == targetNode.data){System.out.println("二叉查找树中已有重复的结点:" + data);return false;}else if (data > targetNode.data) {if(targetNode.right == null){targetNode.right = node;return true;}targetNode = targetNode.right;}else {if(targetNode.left == null){targetNode.left = node;return true;}targetNode = targetNode.left;}}return true;}//删除结点public boolean delete(int data) {Node targetNode = root;Node parentNode = new Node(data);//判断待删除结点是否存在while (targetNode.data != data) {parentNode = targetNode;if (data > targetNode.data) {targetNode = targetNode.right;} else {targetNode = targetNode.left;}if (targetNode == null) {// 没有找到待删除结点return false;}}// 待删除结点没有子节点if (targetNode.right==null && targetNode.left==null) {if (targetNode == root) {//待删除结点是根结点root = null;} else {if (parentNode.right == targetNode) {parentNode.right = null;} else {parentNode.left = null;}}}//待删除结点有一个子结点(右)else if(targetNode.left == null) {if(targetNode == root) {root = targetNode.right;} else if(parentNode.right == targetNode) {parentNode.right = targetNode.right;} else {parentNode.left = targetNode.right;}}//待删除结点有一个子结点(左)else if(targetNode.right == null) {if(targetNode == root) {root = targetNode.left;} else if(parentNode.right == targetNode) {parentNode.right = targetNode.left;} else {parentNode.left = targetNode.left;}}//待删除结点有两个子结点else {//待删除结点的后继结点的父结点Node successParentNode = targetNode;//待删除结点的后继结点Node successNode = targetNode.right;while(successNode.left != null){successParentNode = successNode;successNode = successNode.left;}//把后继结点复制到待删除结点位置targetNode.data = successNode.data;//删除后继结点if(successParentNode.right == successNode) {successParentNode.right = successNode.right;} else {successParentNode.left = successNode.right;}}return true;}// 结点类private class Node {int data;Node right;Node left;Node(int data){this.data = data;}}public static void main(String[] args) {BinarySearchTree tree = new BinarySearchTree();int input[]= {6,3,8,2,5,7,9,1,4};for(int i=0; i<input.length; i++) {tree.insert(input[i]);}inOrderTraversal(tree.root);System.out.println();tree.search(3);tree.delete(3);tree.search(3);tree.delete(6);inOrderTraversal(tree.root);}
}

AVL树

import java.util.LinkedList;
import java.util.Queue;public class AVLTree {private TreeNode root;/** 获取树的高度*/private int height(TreeNode node) {if (node != null)return node.height;return 0;}public int height() {return height(root);}//查找结点public TreeNode search(TreeNode node, int data) {while (node!=null) {if (data < node.data)node = node.left;else if (data > node.data)node = node.right;elsereturn node;}return node;}//左左局面旋转private TreeNode leftLeftRotation(TreeNode node) {//leftChildNode 对应示意图中的结点BTreeNode leftChildNode = node.left;node.left = leftChildNode.right;leftChildNode.right = node;//刷新结点A和结点B的高度node.height = Math.max(height(node.left), height(node.right)) + 1;leftChildNode.height = Math.max(height(leftChildNode.left), node.height) + 1;//返回旋转后的父结点return leftChildNode;}//右右局面旋转private TreeNode rightRightRotation(TreeNode node) {//rightChildNode 对应示意图中的结点BTreeNode rightChildNode = node.right;node.right = rightChildNode.left;rightChildNode.left = node;//刷新结点A和结点B的高度node.height = Math.max(height(node.left), height(node.right)) + 1;rightChildNode.height = Math.max(height(rightChildNode.right), node.height) + 1;//返回旋转后的父结点return rightChildNode;}//左右局面旋转private TreeNode leftRightRotation(TreeNode node) {//先做左旋node.left = rightRightRotation(node.left);//再做右旋return leftLeftRotation(node);}//右左局面旋转private TreeNode rightLeftRotation(TreeNode node) {//先做右旋node.right = leftLeftRotation(node.right);//再做左旋return rightRightRotation(node);}//插入结点public void insert(int data) {root = insert(root, data);}//插入结点详细过程(递归)private TreeNode insert(TreeNode node, int data) {if (node == null) {node = new TreeNode(data);} else {if (data < node.data) {//新结点小于当前结点,选择当前结点的左子树插入node.left = insert(node.left, data);// 插入节点后,若AVL树失去平衡,则进行相应的调节。if (node.getBalance() == 2) {if (data < node.left.data) {node = leftLeftRotation(node);} else {node = leftRightRotation(node);}}} else if (data > node.data)  {//新结点大于当前结点,选择当前结点的右子树插入node.right = insert(node.right, data);// 插入节点后,若AVL树失去平衡,则进行相应的调节。if (node.getBalance() == -2) {if (data > node.right.data) {node = rightRightRotation(node);} else {node = rightLeftRotation(node);}}} else {System.out.println("AVL树中已有重复的结点!");}}//刷新结点的高度node.height = Math.max(height(node.left), height(node.right)) + 1;return node;}//删除结点public void remove(int data) {TreeNode deletedNode;if ((deletedNode = search(root, data)) != null)root = remove(root, deletedNode);}//删除结点详细过程(递归)private TreeNode remove(TreeNode node, TreeNode deletedNode) {// 根为空 或者 没有要删除的节点,直接返回null。if (node==null || deletedNode==null)return null;if (deletedNode.data < node.data){//待删除结点小于当前结点,在当前结点的左子树继续执行node.left = remove(node.left, deletedNode);// 删除节点后,若AVL树失去平衡,则进行相应的调节。if (height(node.right) - height(node.left) == 2) {TreeNode r =  node.right;if (height(r.left) > height(r.right))node = rightLeftRotation(node);elsenode = rightRightRotation(node);}} else  if (deletedNode.data > node.data) {//待删除结点大于当前结点,在当前结点的右子树继续执行node.right = remove(node.right, deletedNode);// 删除节点后,若AVL树失去平衡,则进行相应的调节。if (height(node.left) - height(node.right) == 2) {TreeNode l =  node.left;if (height(l.right) > height(l.left))node = leftRightRotation(node);elsenode = leftLeftRotation(node);}} else {// tree的左右孩子都非空if ((node.left!=null) && (node.right!=null)) {if (height(node.left) > height(node.right)) {// 如果node的左子树比右子树高,找出左子树最大结点赋值给Node,并删除最小结点TreeNode max = maximum(node.left);node.data = max.data;node.left = remove(node.left, max);} else {// 如果node的右子树比左子树高,找出右子树最小结点赋值给Node,并删除最小结点TreeNode min = minimum(node.right);node.data = min.data;node.right = remove(node.right, min);}} else {node = (node.left!=null) ? node.left : node.right;}}node.height = Math.max(height(node.left), height(node.right)) + 1;return node;}//找出结点node为根的子树的最大节点private TreeNode maximum(TreeNode node) {if (node == null)return null;while(node.right != null)node = node.right;return node;}//找出结点node为根的子树的最小节点private TreeNode minimum(TreeNode node) {if (node == null)return null;while(node.left != null)node = node.left;return node;}//中序遍历public static void inOrderTraversal(TreeNode node) {if(node != null) {inOrderTraversal(node.left);System.out.print(node.data+" ");inOrderTraversal(node.right);}}//层序遍历public static void levelOrderTraversal(TreeNode root){Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){TreeNode node = queue.poll();System.out.print(node.data+" ");if(node.left != null){queue.offer(node.left);}if(node.right != null){queue.offer(node.right);}}}class TreeNode {int data;int height;TreeNode left;TreeNode right;public TreeNode(int data) {this.data = data;this.height = 0;}//获得结点的平衡因子public int getBalance(){int left =  (this.left==null ? 0:this.left.height);int right = (this.right==null ? 0:this.right.height);return left - right;}}public static void main(String[] args) {AVLTree tree = new AVLTree();int input[]= {5,3,7,2,4,6,9,1};for(int i=0; i<input.length; i++) {tree.insert(input[i]);}System.out.println("中序遍历: ");inOrderTraversal(tree.root);System.out.println();System.out.println("层序遍历: ");levelOrderTraversal(tree.root);System.out.println();System.out.printf("高度: %d\n", tree.height());int deletedData = 3;System.out.printf("删除根节点: %d\n", deletedData);tree.remove(deletedData);System.out.println("中序遍历: ");inOrderTraversal(tree.root);System.out.println();System.out.println("层序遍历: ");levelOrderTraversal(tree.root);System.out.println();System.out.printf("高度: %d\n", tree.height());}
}

红黑树


import java.util.LinkedList;
import java.util.Queue;public class RedBlackTree {TreeNode root;final static boolean RED = true;final static boolean BLACK = false;//查找结点public TreeNode search(int data) {TreeNode tmp = root;while (tmp != null) {if (tmp.data == data)return tmp;else if (tmp.data > data)tmp = tmp.left;elsetmp = tmp.right;}return null;}//插入结点public boolean insert(int data) {TreeNode node = new TreeNode(data);//局面1:新结点位于树根,没有父结点。if (root == null) {root = node;node.color = BLACK;return true;}TreeNode targetNode = root;while (targetNode != null) {if( data == targetNode.data){System.out.println("红黑树中已有重复的结点:" + data);return false;} else if (data > targetNode.data) {if(targetNode.right == null){targetNode.right = node;node.parent = targetNode;insertAdjust(node);return true;}targetNode = targetNode.right;} else {if(targetNode.left == null){targetNode.left = node;node.parent = targetNode;insertAdjust(node);return true;}targetNode = targetNode.left;}}return true;}//插入后自我调整private void insertAdjust(TreeNode node) {//创建父结点和祖父结点指针TreeNode parent, grandParent;//局面3的调整有可能引发后续的一系列调整,所以使用while循环。while (node.parent != null && node.parent.color == RED) {parent = node.parent;grandParent = parent.parent;if (grandParent.left == parent) {TreeNode uncle = grandParent.right;//局面3:新结点的父结点和叔叔结点都是红色。if (uncle != null && uncle.color == RED) {parent.color = BLACK;uncle.color = BLACK;grandParent.color = RED;node = grandParent;continue;}//局面4:新结点的父结点是红色,叔叔结点是黑色或者没有叔叔,且新结点是父结点的右孩子,父结点是祖父结点的左孩子。if (node == parent.right) {leftRotate(parent);TreeNode tmp = node;node = parent;parent = tmp;}//局面5:新结点的父结点是红色,叔叔结点是黑色或者没有叔叔,且新结点是父结点的左孩子,父结点是祖父结点的左孩子。parent.color = BLACK;grandParent.color = RED;rightRotate(grandParent);} else {TreeNode uncle = grandParent.left;//局面3(镜像):新结点的父结点和叔叔结点都是红色。if (uncle != null && uncle.color == RED) {parent.color = BLACK;uncle.color = BLACK;grandParent.color = RED;node = grandParent;continue;}//局面4(镜像):新结点的父结点是红色,叔叔结点是黑色或者没有叔叔,且新结点是父结点的左孩子,父结点是祖父结点的右孩子。if (node == parent.left) {rightRotate(parent);TreeNode tmp = node;node = parent;parent = tmp;}//局面5(镜像):新结点的父结点是红色,叔叔结点是黑色或者没有叔叔,且新结点是父结点的右孩子,父结点是祖父结点的右孩子。parent.color = BLACK;grandParent.color = RED;leftRotate(grandParent);}}//经过局面3的调整,有可能把根结点变为红色,此时再变回黑色即可。if(root.color == RED){root.color = BLACK;}}//删除节点public void remove(int key) {remove(search(key));}//删除节点详细逻辑private void remove(TreeNode node) {TreeNode targetNode = node;if (node == null)return;//第一步:如果待删除结点有两个非空的孩子结点,转化成待删除结点只有一个孩子(或没有孩子)的情况。if (node.left != null && node.right != null) {//待删除结点的后继结点TreeNode successNode = targetNode.right;while(successNode.left != null) {successNode = successNode.left;}if(targetNode == root) {root = successNode;}//把后继结点复制到待删除结点位置targetNode.data = successNode.data;remove(successNode);return;}//第二步:根据待删除结点和其唯一子结点的颜色,分情况处理。TreeNode successNode = node.left!= null ? node.left : node.right;TreeNode parent = node.parent;if (parent == null) {//子情况1,被删除结点是红黑树的根结点:root = successNode;if (successNode != null)successNode.parent = null;} else {if (successNode != null)successNode.parent = parent;if (parent.left == node)parent.left = successNode;else {parent.right = successNode;}}if (node.color == BLACK )//第三步:遇到双黑结点,在子结点顶替父结点之后,分成6种子情况处理。removeAdjust(parent, successNode);}//删除结点后的自我调整private void removeAdjust(TreeNode parent, TreeNode node) {while ((node == null || node.color == BLACK) && node != root) {if (parent.left == node) {//node的兄弟节点TreeNode sibling = parent.right;//子情况3,node的兄弟结点是红色:if (sibling != null && sibling.color == RED) {parent.color = RED;sibling.color = BLACK;leftRotate(parent);sibling = parent.right;}if (sibling == null || ((sibling.left == null || sibling.left.color == BLACK) && (sibling.right == null || sibling.right.color == BLACK))) {//子情况2(镜像),node的父结点是黑色,兄弟和侄子结点是黑色:if(parent.color == BLACK){sibling.color = RED;node = parent;parent = node.parent;continue;}//子情况4(镜像),node的父结点是红色,兄弟和侄子结点是黑色:else {sibling.color = RED;break;}}//子情况5,node的父结点随意,兄弟结点是黑色右孩子,左侄子结点是红色,右侄子结点是黑色:if (sibling.left == null || sibling.color == RED) {sibling.left.color = BLACK;sibling.color = RED;rightRotate(sibling);sibling = sibling.parent;}//子情况6,结点2的父结点随意,兄弟结点B是黑色右孩子,右侄子结点是红色:sibling.color = parent.color;parent.color = BLACK;sibling.right.color = BLACK;leftRotate(parent);node = root; //跳出循环} else {//node的兄弟节点TreeNode sibling = parent.left;//子情况3(镜像),node的兄弟结点是红色:if (sibling != null && sibling.color == RED) {parent.color = RED;sibling.color = BLACK;rightRotate(parent);sibling = parent.left;}if (sibling == null || ((sibling.left == null || sibling.left.color == BLACK) && (sibling.right == null || sibling.right.color == BLACK))) {//子情况2(镜像),node的父结点是黑色,兄弟和侄子结点是黑色:if(parent.color == BLACK){sibling.color = RED;node = parent;parent = node.parent;continue;}//子情况4(镜像),node的父结点是红色,兄弟和侄子结点是黑色:else {sibling.color = RED;break;}}//子情况5(镜像),node的父结点随意,兄弟结点是黑色左孩子,右侄子结点是红色,左侄子结点是黑色:if (sibling.right == null || sibling.right.color == RED) {sibling.right.color = BLACK;sibling.color = RED;leftRotate(sibling);sibling = sibling.parent;}//子情况6(镜像),结点2的父结点随意,兄弟结点是黑色左孩子,左侄子结点是红色:sibling.color = parent.color;parent.color = BLACK;sibling.left.color = BLACK;rightRotate(parent);node = root; //跳出循环}}if (node != null) {node.color = BLACK;}}//左旋转private void leftRotate(TreeNode node) {TreeNode right = node.right;TreeNode parent = node.parent;if (parent == null) {root = right;right.parent = null;} else {if (parent.left != null && parent.left == node) {parent.left = right;} else {parent.right = right;}right.parent = parent;}node.parent = right;node.right = right.left;if (right.left != null) {right.left.parent = node;}right.left = node;}//右旋转private void rightRotate(TreeNode node) {TreeNode left = node.left;TreeNode parent = node.parent;if (parent == null) {root = left;left.parent = null;} else {if (parent.left != null && parent.left == node) {parent.left = left;} else {parent.right = left;}left.parent = parent;}node.parent = left;node.left = left.right;if (left.right != null) {left.right.parent = node;}left.right = node;}//中序遍历public static void inOrderTraversal(TreeNode node) {if(node != null) {inOrderTraversal(node.left);System.out.print(node);inOrderTraversal(node.right);}}//层序遍历public static void levelOrderTraversal(TreeNode root){Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){TreeNode node = queue.poll();System.out.print(node);if(node.left != null){queue.offer(node.left);}if(node.right != null){queue.offer(node.right);}}}class TreeNode {int data;boolean color;TreeNode left;TreeNode right;TreeNode parent;public TreeNode(int data) {this.data = data;this.color = RED;}@Overridepublic String toString() {return  data + (color?"(red)":"(black)") + "  " ;}}public static void main(String[] args) {RedBlackTree rbTree = new RedBlackTree();int input[]= {13,8,17,1,11,15,25,6,22,27};for(int i=0; i<input.length; i++) {rbTree.insert(input[i]);}rbTree.remove(8);System.out.println("中序遍历: ");inOrderTraversal(rbTree.root);System.out.println();System.out.println("层序遍历: ");levelOrderTraversal(rbTree.root);System.out.println();}
}

《漫画算法2》源码整理-1 二分查找树 AVL树 红黑树相关推荐

  1. 《漫画算法2》源码整理-3 二分查找 跳跃表

    二分查找 public class BinarySearch {public static int binarySearch(int[] array, int target) {//查找范围起点int ...

  2. 《漫画算法》源码整理-7

    MyBitmap public class MyBitmap {//每一个word是一个long类型元素,对应64位二进制private long[] words;//bitmap的位数大小priva ...

  3. 《漫画算法》源码整理-5 排序算法

    冒泡排序 import java.util.Arrays;public class BubbleSort {public static void sort(int array[]){int tmp = ...

  4. 《漫画算法》源码整理-6

    判断链表有环 public class LinkedListCycle {/*** 判断是否有环* @param head 链表头节点*/public static boolean isCycle(N ...

  5. 《漫画算法》源码整理-4 大顶堆 小顶堆 优先队列

    堆操作 import java.util.Arrays;public class HeapOperator {/*** 上浮调整* @param array 待调整的堆*/public static ...

  6. 《漫画算法》源码整理-3 二叉树遍历

    二叉树前序 中序 后序 遍历 import java.util.Arrays; import java.util.LinkedList;public class BinaryTreeTraversal ...

  7. 《漫画算法》源码整理-2 数组 链表 队列

    数组操作 public class MyArray {private int[] array;private int size;public MyArray(int capacity){this.ar ...

  8. 《漫画算法》源码整理-1 时间复杂度 空间复杂度

    时间复杂度 public class TimeComplex {void eat1(int n){for(int i=0; i<n; i++){;System.out.println(" ...

  9. java计算机毕业设计漫画网站系统源码+系统+数据库+lw文档+mybatis+运行部署

    java计算机毕业设计漫画网站系统源码+系统+数据库+lw文档+mybatis+运行部署 java计算机毕业设计漫画网站系统源码+系统+数据库+lw文档+mybatis+运行部署 本源码技术栈: 项目 ...

最新文章

  1. 《windows核心编程系列》十八谈谈windows钩子
  2. LOOP WITH CONTROL 用法
  3. [渝粤教育] 西南科技大学 财务管理与分析 在线考试复习资料
  4. 三层加过的注释java_spring框架中三层架构相关的注解
  5. jdbcTemplate查询方法
  6. 2014-7 Andrew Ng 自动化所报告听后感
  7. 非域环境下安装并配置Project Server 2007(二)
  8. 自己动手写操作系统——开发环境搭建
  9. 字节跳动面试真题:2021新一波程序员跳槽季,系列篇
  10. 关于sql注入漏洞的挖掘及渗透工具简介
  11. onscripter For windows/MAC OS 中文版
  12. linux 主机上的串口工具,Linux实用工具-kermit使用总结
  13. Navicat Premium v12.0.23.0 破解教程x86,x64通用,手动破解
  14. MAC M1 芯片在 yarn install 时报错:The CPU architecture “arm64“
  15. 涉密信息系统集成资质申请单位提交材料清单
  16. 有无可能在非IOS系统上实现苹果为网易/腾讯邮箱做的实时推送
  17. 汽车UDS诊断详解及Vector相关工具链使用说明——6.2 VT System 入门
  18. 三段式过流保护、差动保护
  19. 华为云计算机访问手机软件,华为云电脑来了,只需一个APP就能让手机秒变Windows电脑...
  20. Git for Windows 国内下载站,免翻快速下载安装

热门文章

  1. commons-lang常用工具类StringEscapeUtils使用--转
  2. Disruptor 源码阅读笔记--转
  3. How to Setup Replicated LevelDB Persistence in Apache ActiveMQ 5.9--转载
  4. AOP 的利器:ASM 3.0 介绍
  5. MySQL——MySQL的数据查询功能
  6. 智能风控平台核心之风控决策引擎(二)
  7. java getresourceasstream null_java踩坑记-getResourceAsStream
  8. [搜索]波特词干(Porter Streamming)提取算法详解(2)
  9. 白话Elasticsearch20-深度探秘搜索技术之使用rescoring机制优化近似匹配搜索的性能
  10. Quartz-JobListener解读