跳到主要内容图数据结构详解:基于 Java 的雷达扫描系统实现 | 极客日志Javajava算法
图数据结构详解:基于 Java 的雷达扫描系统实现
综述由AI生成图数据结构的基本概念,包括顶点和边的定义,以及无向加权图的应用场景。通过 Java 语言实现了邻接表存储结构,设计了 Edge 和 MPoint 类来管理节点与边。详细分析了 Graph 类的核心方法,如添加顶点、扫描添加边及信息显示。结合 Swing 构建了交互式图形界面,并针对初始 UI 体验进行了优化,增加了距离滑杆显示和最短路径节点颜色区分功能,直观模拟雷达扫描效果。
FrontendX39 浏览 引言
想象一下这样的场景:一架无人机正在执行侦查任务,它需要扫描周围环境,记录各个入侵者的位置,并计算这些点之间的距离关系,便于攻击等。这正是我们项目要解决的问题,而图数据结构就是解决这类问题的完美选择。
什么是图?
1.图的基本概念
图是由**顶点(Vertex)和边(Edge)**组成的非线性数据结构。在我们的雷达扫描项目中:
- 顶点:每个雷达扫描到的目标点(如 X, A, B, C 等)
- 边:两个目标点之间的连接,带有距离(权重)信息
数学上,一个图 G 可以表示为:G = (V, E),其中:
2.图的类型
在我们的项目中,我们构建的是无向加权图:
- 无向:边没有方向,A 到 B 的距离等于 B 到 A 的距离
- 加权:每条边都有一个权重值(距离)
我们的图结构示意图:

如何构建图?
1.基础数据结构设计
首先,我们需要定义图的基本组成元素。在 Graph 类中,我们设计了两个核心类:
Edge 类:表示图的边
class Edge {
String name;
int distance;
public Edge(String name, int distance) {
this.name = name;
this.distance = distance;
}
}
每个边记录 目标节点名称 和 距离 适合表示雷达扫描中"从当前点到目标点"的关系
MPoint 类:表示图的顶点
class MPoint {
String name;
int x, y;
public {
.name = name;
.x = x;
.y = y;
}
}
MPoint
(String name, int x, int y)
this
this
this
除了节点名称,还存储了 坐标位置 这反映了雷达扫描的实际需求:知道目标点的具体位置坐标信息可以用于计算两点之间的直线距离
2.图的核心数据结构
public class Graph {
Map<String, List<Edge>> graph = new HashMap<>();
}
2.1 而什么是邻接表呢?
邻接表是图的一种链式存储结构,它通过为图中的每个顶点建立一个链表,来存储该顶点的所有邻接点(相邻顶点)。
Map<String, List<Edge>> graph = new HashMap<>();
- 键(Key):顶点的名称(String 类型)
- 值(Value):该顶点的邻接边列表(List 类型)
- Edge 对象:存储目标顶点名称和距离权重
2.2 实际存储实例
顶点:X, A, B, C 边:X-A(150), X-B(200), X-C(180), A-B(100), A-C(120)
graph = {
"X": [Edge("A",150), Edge("B",200), Edge("C",180)],
"A": [Edge("X",150), Edge("B",100), Edge("C",120)],
"B": [Edge("X",200), Edge("A",100)],
"C": [Edge("X",180), Edge("A",120)]
};
核心方法分析
1.add 方法:添加顶点
public void add(String name) {
List<Edge> edgeList = new ArrayList<>();
graph.put(name, edgeList);
}
创建顶点的邻接边列表为后续添加边做准备确保每个顶点都有对应的数据结构
2.scan 方法:添加边
public void scan(String name, String to, int distance) {
if (!graph.containsKey(name)) {
add(name);
}
if (!graph.containsKey(to)) {
add(to);
}
Edge edge = new Edge(to, distance);
List<Edge> edgeList = graph.get(name);
for (int i = 0; i < edgeList.size(); i++) {
Edge e1 = edgeList.get(i);
if(e1.name.equals(edge.name)) {
return;
}
}
edgeList.add(edge);
Edge edge1 = new Edge(name, distance);
List<Edge> edgeList1 = graph.get(to);
for (int i = 0; i < edgeList1.size(); i++) {
Edge e1 = edgeList1.get(i);
if(e1.name.equals(edge1.name)) {
return;
}
}
edgeList1.add(edge1);
}
自动顶点创建:如果顶点不存在,自动创建。这简化了调用逻辑。重复边检查:避免图中出现重复的边,保证数据的一致性。双向边添加:因为我们构建的是无向图,所以需要添加两个方向的边。
3.showInfo 方法:显示图信息
public void showInfo() {
Set<String> keySet = graph.keySet();
System.out.println("=== 雷达扫描图 ===");
for (String key : keySet) {
List<Edge> edges = graph.get(key);
System.out.println("顶点 -> " + key);
for (int i = 0; i < edges.size(); i++) {
for (int j = 0; j < edges.size()-1; j++) {
Edge e1 = edges.get(j);
Edge e2 = edges.get(j+1);
if(e1.distance > e2.distance) {
edges.set(j, e2);
edges.set(j+1, e1);
}
}
}
for (Edge edge : edges) {
System.out.print(edge.name + "(" + edge.distance + ") ");
}
System.out.println("---------");
}
}
信息展示:清晰地展示图的完整结构距离排序:使用冒泡排序将边按距离从小到大排列可读性:格式化输出,便于调试和理解图结构
交互系统设计
1.GraphRobot 类:用户界面
public class GraphRobot {
public void showUI() {
JFrame jf = new JFrame();
jf.setTitle("图算法应用");
jf.setSize(800, 1000);
g.fillRect(200, 700, 100, 100);
}
}
2.RobotListener 类:监听器
public class RobotListener extends MouseAdapter implements MouseListener {
Graphics g;
final int x = 200;
final int y = 700;
char name = 'A';
Graph scanGraph = new Graph();
ArrayList<MPoint> pointList = new ArrayList<>();
public RobotListener() {
scanGraph.add("X");
pointList.add(new MPoint("X", 200, 700));
}
@Override
public void mousePressed(MouseEvent e) {
int x1 = e.getX();
int y1 = e.getY();
g.setColor(Color.GREEN);
g.fillOval(x1, y1, 50, 50);
int distance = (int) Math.sqrt(Math.pow(x1-x, 2) + Math.pow(y1-y, 2));
scanGraph.scan("X", name + "", distance);
for (int i = 0; i < pointList.size(); i++) {
MPoint p = pointList.get(i);
int distance1 = (int) Math.sqrt(Math.pow(x1 - p.x, 2) + Math.pow(y1 - p.y, 2));
scanGraph.scan(p.name, name + "", distance1);
}
MPoint p1 = new MPoint(name + "", x1, y1);
pointList.add(p1);
name++;
scanGraph.showInfo();
}
}
交互系统展示
(可以看到这样的交互性和观感太差了,距离啥的只能通过输出框展现,数据冗杂且阅读性差)
因此我们进行以下两个方面的优化:1.在 UI 界面右侧新增距离显示功能,将距离算法的结果用滑杆的方式直观表达。2.将距离黑色方块最短距离的圆的颜色由绿变红,直观迅速模拟雷达扫描。
项目优化
1.第一步:修改 GraphRobot 类中的主界面(新增滑杆组件)
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.Y_AXIS));
JLabel distanceLabel = new JLabel("当前距离:0");
distanceLabel.setFont(new Font("宋体", Font.PLAIN, 20));
JSlider distanceSlider = new JSlider(JSlider.VERTICAL, 0, 800, 0);
distanceSlider.setMajorTickSpacing(100);
distanceSlider.setMinorTickSpacing(50);
distanceSlider.setPaintTicks(true);
distanceSlider.setPaintLabels(true);
sliderPanel.add(distanceLabel);
sliderPanel.add(distanceSlider);
jf.add(sliderPanel, BorderLayout.EAST);
在 GraphRobot 中新增滑杆(JSlider)和标签组件,布局改为 BorderLayout 将滑杆放在右侧;同时将滑杆和标签传给 RobotListener,在鼠标点击时更新滑杆值和标签文本,直观显示当前点击点到初始点 X 的距离。
2.第二步:修改 RobotListener 核心逻辑(让最短距离圆变红)
distanceSlider.setValue(distance);
distanceLabel.setText("距离:"+distance);
repaintPoints();
}
private void repaintPoints() {
MPoint shortestPoint = findShortestDistancePoint();
for (MPoint p : pointList) {
if (p.equals(shortestPoint)) {
g.setColor(Color.RED);
} else {
g.setColor(Color.GREEN);
}
g.fillOval(p.x, p.y, 50, 50);
}
g.setColor(Color.BLACK);
g.fillRect(200,700,100,100);
}
private MPoint findShortestDistancePoint() {
MPoint shortestPoint = pointList.get(0);
int minDistance = Integer.MAX_VALUE;
for (MPoint p : pointList) {
if (p.name.equals("X")) {
continue;
}
int distance = (int) Math.sqrt(Math.pow(p.x - x, 2) + Math.pow(p.y - y, 2));
if (distance < minDistance) {
minDistance = distance;
shortestPoint = p;
}
}
return shortestPoint;
}
}
新增 findShortestDistancePoint() 方法,遍历所有节点找到距离初始点 X 最短的节点(原有逻辑)新增 repaintPoints() 方法,重新绘制所有节点,最短距离节点用红色,其余保持绿色;在鼠标点击后调用 repaintPoints(),确保每次新增节点后立即更新颜色。
3.保留原有逻辑的关键点
未修改 Graph 类的核心图结构和算法;未改变原有鼠标点击绘制绿色圆的基础逻辑,仅新增了最短距离节点的颜色区分;滑杆组件为新增,未破坏原有窗口布局的核心逻辑。
项目优化后展示
结语
图数据结构是计算机科学中最美、最强大的数据结构之一。图结构就像一张智慧的网,连接着数据与现实世界,帮助我们洞察复杂的关系和模式。通过这个雷达扫描项目,我不仅学会了如何实现图,更重要的是理解了好的数据结构不是目的,而是解决问题的手段。当我们面对复杂的关系网络时,图数据结构就是我们最有力的工具之一。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online