中位数 Median 即中数,是有序序列中处于中间位置的数,求解数据库及数据流中的中位数。
众数、中位数、平均数的区别 众数、中位数、平均数都用来描述数据的集中趋势
中位数:有序序列,中间位置的数
众数:出现频次最高的数
平均数:算数平局数 = 总数 / 个数
例题
Numbers
表: +-------------+------+ | Column Name | Type | +-------------+------+ | num | int | | frequency | int | +-------------+------+ num 是这张表的主键。这张表的每一行表示某个数字在该数据库中的出现频率。 中位数 是将数据样本中半数较高值和半数较低值分隔开的值。 编写一个 SQL 查询,解压 Numbers 表,报告数据库中所有数字的 中位数 。结果四舍五入至 一位小数 。 查询结果如下例所示。 输入: Numbers 表: +-----+-----------+ | num | frequency | +-----+-----------+ | 0 | 7 | | 1 | 1 | | 2 | 3 | | 3 | 1 | +-----+-----------+ 输出: +--------+ | median | +--------+ | 0.0 | +--------+ 解释: 如果解压这个 Numbers 表,可以得到 [0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3] ,所以中位数是 (0 + 0) / 2 = 0 。
SQL
中的聚合函数和开窗函数SUM()
COUNT()
AVG()
MAX()
MIN()
OVER()
开窗函数使用
GROUP BY
使用
>
总频次一半的行即解SElECT AVG(num) as median FROM (
SElECT num,
SUM(frequency) OVER (ORDER BY num) AS sum_asc,
SUM(frequency) OVER (ORDER BY num DESC) AS sum_desc,
SUM(frequency) OVER () AS sum
FROM Numbers
) tmp WHERE sum_asc >= sum / 2 AND sum_desc >= sum / 2
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操作的数据结构: void addNum(int num) - 从数据流中添加一个整数到数据结构中。 double findMedian() - 返回目前所有元素的中位数。
先放入哪个队列,都没有关系,只需要
var MedianFinder = function() {
this.minHeap = new PriorityQueue([], (a, b) => a - b)
this.maxHeap = new PriorityQueue([], (a, b) => b - a)
};
MedianFinder.prototype.addNum = function(num) {
if (this.maxHeap.size === this.minHeap.size) {
this.minHeap.push(this.maxHeap.push(num).pop())
} else {
this.maxHeap.push(this.minHeap.push(num).pop())
}
};
MedianFinder.prototype.findMedian = function() {
if (this.maxHeap.size === this.minHeap.size) {
return (this.maxHeap.top() + this.minHeap.top()) / 2
} else {
return this.minHeap.top()
}
};
class PriorityQueue {
constructor (ar = [], compare = (a, b) => a - b) {
this.heap = []
this.size = 0
this.compare = compare
while (ar.length) this.push(ar.pop())
}
swap (a, b) {
const tmp = this.heap[a]
this.heap[a] = this.heap[b]
this.heap[b] = tmp
}
getParentIndex (index) {
return index - 1 >> 1
}
getLeftIndex (index) {
return (index << 1) + 1
}
getRightIndex (index) {
return (index << 1) + 2
}
shiftUp (index) {
const paretIndex = this.getParentIndex(index)
if (this.compare(this.heap[paretIndex], this.heap[index]) > 0) {
this.swap(paretIndex, index)
this.shiftUp(paretIndex)
}
}
shiftDown (index) {
const leftIndex = this.getLeftIndex(index)
const rightIndex = this.getRightIndex(index)
if (this.compare(this.heap[index], this.heap[leftIndex]) > 0) {
this.swap(leftIndex, index)
this.shiftDown(leftIndex)
}
if (this.compare(this.heap[index], this.heap[rightIndex]) > 0) {
this.swap(rightIndex, index)
this.shiftDown(rightIndex)
}
}
push (value) {
this.heap.push(value)
this.shiftUp(this.size++)
return this
}
top () {
return this.heap[0]
}
pop () {
if (this.size === 0) return null
if (--this.size === 0) return this.heap.pop()
const top = this.top()
this.heap[0] = this.heap.pop()
this.shiftDown(0)
return top
}
isEmpty () {
return this.size === 0
}
}