[剑指offer]数据流中的中位数
时间:2019-10-23
本文章向大家介绍[剑指offer]数据流中的中位数,主要包括[剑指offer]数据流中的中位数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
题目链接:
实现:维持了一个根节点左右子树相差不到1相同的树。
package com.sunshine.OFFER66_SECOND; public class BalanceTreeNode { int val; int height; BalanceTreeNode left; BalanceTreeNode right; BalanceTreeNode(int val) { this.height = 1; this.val = val; } }
package com.sunshine.OFFER66_SECOND; import org.junit.Test; public class A63_GetMedian { @Test public void test() { //[5,2,3,4,1,6,7,0,8] //5.00 3.50 3.00 3.50 3.00 3.50 4.00 3.50 4.00 Insert(5); Insert(2); Insert(3); Insert(4); Insert(1); Insert(6); Insert(7); Insert(0); Insert(8); } private BalanceTreeNode root = null; public void Insert(Integer num) { root = Insert(root, num); // Double ans = GetMedian(); // System.out.println(ans); // TreeUtility.printTreeOfLine(root); // System.out.println("=========="); } public Double GetMedian() { if (null == root) { return 0.0; } int leftTreeHeight = getTreeHeight(root.left); int rightTreeHeight = getTreeHeight(root.right); if (leftTreeHeight == rightTreeHeight) { return root.val + 0.0; } else { if (leftTreeHeight > rightTreeHeight) { BalanceTreeNode tmp = root.left; while (null != tmp.right) { tmp = tmp.right; } return (root.val + tmp.val) / 2.0; } else { BalanceTreeNode tmp = root.right; while (null != tmp.left) { tmp = tmp.left; } return (root.val + tmp.val) / 2.0; } } } private int getTreeHeight(BalanceTreeNode node) { if (null == node) { return 0; } return node.height; } private int getBalanceFactor(BalanceTreeNode node) { if (null == node) { return 0; } return getTreeHeight(node.left) - getTreeHeight(node.right); } private int getMax(BalanceTreeNode cur) { if(null == cur){ return 0; } int leftHeight = getTreeHeight(cur.left); int rightHeight = getTreeHeight(cur.right); // return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; return leftHeight + rightHeight + 1; } private BalanceTreeNode Insert(BalanceTreeNode cur, Integer num) { if (null == cur) { cur = new BalanceTreeNode(num); return cur; } if (cur.val >= num) { cur.left = Insert(cur.left, num); } else if (cur.val < num) { cur.right = Insert(cur.right, num); } cur.height = getMax(cur); int balanceFactor = getBalanceFactor(cur); if (balanceFactor > 1) { //LL if (num < cur.left.val) { return LLRotate(cur); } //LR else { return LRRotate(cur); } } if (balanceFactor < -1) { //RR if (num > cur.right.val) { return RRRotate(cur); } //RL else { return RLRotate(cur); } } return cur; } private BalanceTreeNode LLRotate(BalanceTreeNode cur) { BalanceTreeNode tmp = cur.left; BalanceTreeNode preTmp = null; // tmp.height = cur.height + 1; // cur.height = getTreeHeight(tmp.right) + getTreeHeight(cur.right) + 1; // cur.left = tmp.right; // tmp.right = cur; while (null != tmp.right) { tmp.height--; preTmp = tmp; tmp = tmp.right; } if (tmp != cur.left) { preTmp.right = tmp.left; tmp.left = cur.left; } tmp.right = cur; cur.left = null; tmp.height = cur.height + 1; cur.height = getMax(cur); if(null != preTmp) { preTmp.height = getMax(preTmp); } return tmp; } private BalanceTreeNode LRRotate(BalanceTreeNode cur) { cur.left = RRRotate(cur.left); cur = LLRotate(cur); return cur; } private BalanceTreeNode RRRotate(BalanceTreeNode cur) { BalanceTreeNode tmp = cur.right; BalanceTreeNode preTmp = null; // tmp.height = cur.height + 1; // cur.height = getTreeHeight(tmp.left) + getTreeHeight(cur.left) + 1; // cur.right = tmp.left; // tmp.left = cur; while (null != tmp.left) { tmp.height--; preTmp = tmp; tmp = tmp.left; } if (tmp != cur.right) { preTmp.left = tmp.right; tmp.right = cur.right; } tmp.left = cur; cur.right = null; tmp.height = cur.height + 1; cur.height = getMax(cur); if(null != preTmp) { preTmp.height = getMax(preTmp); } return tmp; } private BalanceTreeNode RLRotate(BalanceTreeNode cur) { cur.right = LLRotate(cur.right); cur = RRRotate(cur); return cur; } }
建树过程:
5.0 5 # # ========== 3.5 5 2 # # # ========== 3.0 3 2 5 # # # # ========== 3.5 3 2 5 # # 4 # # # ========== 3.0 3 2 5 1 # 4 # # # # # ========== 3.5 3 2 5 1 # 4 6 # # # # # # ========== 4.0 4 3 5 2 # # 6 1 # # 7 # # # # ========== 3.5 3 2 4 1 # # 5 0 # # 6 # # # 7 # # ========== 4.0 4 3 5 2 # # 6 1 # # 7 0 # # 8 # # # # ========== Process finished with exit code 0
原文地址:https://www.cnblogs.com/MoonBeautiful/p/11725318.html
- 左手用R右手Python系列——面向对象编程基础
- 线性同余同余方程组解法(excrt)
- #19. 计数(容斥原理)
- 左手用R右手Python系列——多进程/线程数据抓取与网页请求
- #15. 钻石
- P1328 生活大爆炸版石头剪刀布
- ASP.NET MVC 5 Authentication Breakdown
- jquery easyui datagrid mvc server端分页排序筛选的实现
- 左手用R右手Python系列——使用多进程进行任务处理
- 2017.9.17校内noip模拟赛解题报告
- MySQL基础入门——MySQL与R语言、Python交互
- BizTalk Orchestration execute Flat file disassembler ReceivePipeline
- MySQL基础入门系列之——字符与日期数据处理
- P2038 无线网络发射器选址
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ggplot2|从0开始绘制PCA图
- Python字典
- 如何用R语言绘制生成正态分布图表
- ggplot2-plotly|让你的火山图“活”过来
- 小数据| 描述性统计(Python/R 实现)
- ggplot2|发散性“正负”图
- R语言蒙特卡洛计算和快速傅立叶变换计算矩生成函数
- pheatmap|暴雨暂歇,“热图”来袭!!!
- 统一服务消息接口报48001错误
- ggplot2|ggpubr进行“paper”组图合并
- PostgreSQL drop table 空间不释放的问题解决
- R语言预测人口死亡率:用李·卡特模型、非线性模型进行平滑估计
- Dockerfile 指令
- Docker 构建容器Tomcat+Nginx+MySQL
- 三种动态控制SAP CRM WebClient UI assignment block显示与否的方法