Java 树结构:查找元素和保存父元素链的最佳方法
我有一个JSONObject,它可以有相同类型的子JSONArray。我想迭代它,找到我需要的元素并保存父元素链(例如,找到的元素是这个元素的子元素,这个元素是下一个元素的子元素,下一个元素是根元素的子元素) 目前,这是我的天真实现:Java 树结构:查找元素和保存父元素链的最佳方法,java,algorithm,tree,Java,Algorithm,Tree,我有一个JSONObject,它可以有相同类型的子JSONArray。我想迭代它,找到我需要的元素并保存父元素链(例如,找到的元素是这个元素的子元素,这个元素是下一个元素的子元素,下一个元素是根元素的子元素) 目前,这是我的天真实现: private boolean found; private void searchNode(List<JSONObject> chain, JSONObject rootNode, JSONObjec
private boolean found;
private void searchNode(List<JSONObject> chain,
JSONObject rootNode, JSONObject desiredFrame) {
if (found)
return;
JSONArray children = rootNode.getJSONArray("frames");
chain.add(rootNode);
for (int i = 0; i < children.length(); i++) {
JSONObject currentNode = children.getJSONObject(i);
if (currentNode.equals(desiredNode)) {
found = true;
chain.add(currentNode);
return;
}
searchNode(chain, currentNode, desiredNode);
if (!found)
chain.remove(currentNode);
}
找到私有布尔值;
私有无效搜索节点(列表链,
JSONObject根节点,JSONObject desiredFrame){
如果(找到)
返回;
JSONArray children=rootNode.getJSONArray(“frames”);
添加(rootNode);
for(int i=0;i
我可以看到哪些问题:
private boolean found;
private void searchNode(List<JSONObject> chain,
JSONObject rootNode, JSONObject desiredFrame) {
if (found)
return;
JSONArray children = rootNode.getJSONArray("frames");
chain.add(rootNode);
for (int i = 0; i < children.length(); i++) {
JSONObject currentNode = children.getJSONObject(i);
if (currentNode.equals(desiredNode)) {
found = true;
chain.add(currentNode);
return;
}
searchNode(chain, currentNode, desiredNode);
if (!found)
chain.remove(currentNode);
}
此结构可以命名为tree,但此结构不是二进制结构。代码可能存在一些问题:
- 您可以用
的结果替换共享标志searchNode
found
- 您正在比较一个
是否等于。我建议使用JSONObject
检查它是否为正确的节点谓词
可以返回rootNode.getJSONArray(“frames”)
或空数组,但从不检查它null
- 您还可以使用
而不是Stack
来跟踪路径。它可以简化您的算法List
private static boolean searchNode(Stack<JSONObject> chain,
JSONObject currentNode, Predicate<JSONObject> condition) throws Exception {
if (condition.test(currentNode)) {
chain.push(currentNode);
return true;
}
JSONArray children = currentNode.getJSONArray("frames");
if (children == null) {
return false;
}
for (int i = 0; i < children.length(); i++) {
if (searchNode(chain, children.getJSONObject(i), condition)) {
chain.push(currentNode);
return true;
}
}
return false;
}
私有静态布尔搜索节点(堆栈链,
JSONObject currentNode,谓词条件)引发异常{
if(条件测试(当前节点)){
推链(currentNode);
返回true;
}
JSONArray childrent=currentNode.getJSONArray(“帧”);
if(children==null){
返回false;
}
for(int i=0;i
代码中的一些潜在问题:
- 您可以用
的结果替换共享标志searchNode
found
- 您正在比较一个
是否等于。我建议使用JSONObject
检查它是否为正确的节点谓词
可以返回rootNode.getJSONArray(“frames”)
或空数组,但从不检查它null
- 您还可以使用
而不是Stack
来跟踪路径。它可以简化您的算法List
private static boolean searchNode(Stack<JSONObject> chain,
JSONObject currentNode, Predicate<JSONObject> condition) throws Exception {
if (condition.test(currentNode)) {
chain.push(currentNode);
return true;
}
JSONArray children = currentNode.getJSONArray("frames");
if (children == null) {
return false;
}
for (int i = 0; i < children.length(); i++) {
if (searchNode(chain, children.getJSONObject(i), condition)) {
chain.push(currentNode);
return true;
}
}
return false;
}
私有静态布尔搜索节点(堆栈链,
JSONObject currentNode,谓词条件)引发异常{
if(条件测试(当前节点)){
推链(currentNode);
返回true;
}
JSONArray childrent=currentNode.getJSONArray(“帧”);
if(children==null){
返回false;
}
for(int i=0;i
这里有一个更好的算法来搜索您的对象
您不必维护已找到的字段或将链作为参数传递
相反,一旦找到对象,就使用递归调用的返回值来构建链
List<JSONObject> search(JSONObject node, JSONObject searchTerm) {
if (node.equals(searchTerm)) {
List<JSONObject> chain = new List<>();
chain.add(node);
return chain;
} else {
List chain = new Collections.emptyList();
for (JSONObject child: node.getJSONArray("frames")) {
chain = search(child, searchTerm);
if (chain.length > 0) {
chain.add(0, node);
break;
}
}
return chain;
}
}
列表搜索(JSONObject节点,JSONObject搜索项){
if(node.equals(searchTerm)){
列表链=新列表();
添加(节点);
返回链;
}否则{
List chain=new Collections.emptyList();
for(JSONObject子节点:node.getJSONArray(“帧”)){
链=搜索(子项、搜索项);
如果(链长度>0){
添加(0,节点);
打破
}
}
返回链;
}
}
这里有一个更好的算法来搜索您的对象
您不必维护已找到的字段或将链作为参数传递
相反,一旦找到对象,就使用递归调用的返回值来构建链
List<JSONObject> search(JSONObject node, JSONObject searchTerm) {
if (node.equals(searchTerm)) {
List<JSONObject> chain = new List<>();
chain.add(node);
return chain;
} else {
List chain = new Collections.emptyList();
for (JSONObject child: node.getJSONArray("frames")) {
chain = search(child, searchTerm);
if (chain.length > 0) {
chain.add(0, node);
break;
}
}
return chain;
}
}
列表搜索(JSONObject节点,JSONObject搜索项){
if(node.equals(searchTerm)){
列表链=新列表();
添加(节点);
返回链;
}否则{
List chain=new Collections.emptyList();
for(JSONObject子节点:node.getJSONArray(“帧”)){
链=搜索(子项、搜索项);
如果(链长度>0){
添加(0,节点);
打破
}
}
返回链;
}
}
您能否提供一个示例,说明JSON的外观以及您希望从中提取什么?我认为此实现很好:深度优先搜索您能否提供一个示例,说明JSON的外观以及您希望从中提取什么?我认为此实现很好:深度优先搜索正是为了做到这一点正确-你应该添加链,添加(0,父级),但不添加子级-你以前做过。捕捉得好。谢谢。只要做得正确-你应该添加链,添加(0,父级),但不添加子级-你以前做过。捕捉得好。谢谢。