面试官问实现Top K 用什么方式,于是我拿出手Java Swing 实现了堆排序的演示过程。吊打面试官
原创 今夜写代码 今夜写代码 2024-06-26 20:58 浙江
问题背景
关于标题中的Top K 问题,很适合用堆排序,因为堆排序每次建立堆,就知道了一个最值,无需将所有集合排完序,时间复杂度为 K log(N)。本想找个动画直观演示堆排序过程,发现没有,那就自己写一个吧。效果见上图,本文用到的技术
- 完全二叉树
-
- 父子节点下标关系
- 元素个数与树高度关系
- 堆排序实现过程
- Swing
-
-
自定义组件 paintComponent
-
刷新组件 repaint()
-
数组元素以二叉树展示实现
二叉树知识复习
1)完全二叉树数组下标i 的元素左孩子下标:2* i +1右孩子下标:2* i + 22)第 i 层 (i 从0开始) 最多有 2^i 个元素
如何保证画出来的二叉树对称,无重叠
我的解决方法是先考虑满二叉树最后一层,将最后一层水平,按照固定间距放置,即最后一层 相邻之间节点 之间Δx 差值相同,y值相同。除了最后一层,其他层的元素位置由左右孩子决定的,即父节点 x 值取平均值,y 值减 Δx,效果图与伪代码如下
int left = 2 * i + 1;int right = 2 * i + 2;xValues[i] = (xValues[left] + xValues[right]) / 2;yValues[i] = yValues[left] - H_SPAN;
如果树不是满二叉树也不要紧,也按照满二叉树位置放置,多余的位置不显示而已。
Java Swing 绘制节点前面已经计算出每个节点的左边,文本可以用JLabel 实现,考虑要画个圈,我们extends JLabel 重写下paintComponent 画个圆
protected void paintComponent(Graphics g) { super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(Color.RED); g2d.setStroke(new BasicStroke(3)); g2d.drawOval(0, 0, WIDTH, HEIGHT); g2d.dispose(); }
父子节点之间画线,就实现上面二叉树效果,接下来是排序中间状态记录
排序状态动画实现
定义三种状态,正常、比较中、交换
public enum BiNodeStatus { NORMAL, COMPARE, SWAP;}
节点不同状态字体背景色不同,流程图如下图
switch (nodeStatus){
case NORMAL:
setBackground(null);
setForeground(Color.BLACK);
break;
case COMPARE:
setBackground(Color.RED);
break;
case SWAP:
setForeground(Color.BLUE);
break;
default:
setBackground(null);
break;
}
最后完整代码已经上传,请多斧正,未来陆续实现其他排序