- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这就是我要插入到树中的内容:
我正在寻找:Node nd = searchNodeIterativly(root, "Ortiz");
我得到一个空指针错误。
由于"Ortiz"
实际上在树中,我不明白为什么我在循环中的返回不起作用。
是算法,还是我忽略的东西?
这是我的代码:
import java.io.IOException;
import java.util.*;
public class BinaryTree {
public static class Node {
String name, number;
Node Llink, Rlink;
boolean Ltag, Rtag;
Node(String name, String number) {
this.name = name;
this.number = number;
Llink = null;
Rlink = null;
}
}
public static Node insert(Node node, String name, String num) {
// Searching for a Node with given value
Node Q = node;
Node P = null; // Parent of key to be inserted
while (Q != null) {
// If key already exists, return
if (name == (Q.name)) {
System.out.printf("Duplicate Key !\n");
return node;
}
P = Q;
if (name.compareTo(Q.name) < 0) {
if (Q.Ltag == false)
Q = Q.Llink;
else
break;
} else {
if (Q.Rtag == false)
Q = Q.Rlink;
else
break;
}
}
Node tmp = new Node(name, num);
tmp.name = name;
tmp.Ltag = true;
tmp.Rtag = true;
if (P == null) {
node = tmp;
tmp.Llink = null;
tmp.Rlink = null;
} else if (name.compareTo(P.name) < 0) {
tmp.Llink = P.Llink;
tmp.Rlink = P;
P.Ltag = false;
P.Llink = tmp;
} else {
tmp.Llink = P;
tmp.Rlink = P.Rlink;
P.Rtag = false;
P.Rlink = tmp;
}
return node;
}
public static Node searchNodeIterativly(Node node, String name) {
while (node != null) {
if (name.compareTo(node.name) > 0) {
node = node.Llink;
} else if (name.compareTo(node.name) < 0) {
node = node.Rlink;
} else {
return node;
}
}
return node;
}
public static void main(String[] args) throws IOException {
// BinaryTree tree = new BinaryTree();
Node root = new Node("Moutafis ", "295-1492");
insert(root, "Ikerd ", "291-1864");
insert(root, "Gladwin ", "295-1601");
insert(root, "Robson ", "293-6122");
insert(root, "Dang ", "295-1882");
insert(root, "Bird ", "291-7890");
insert(root, "Harris ", "294-8075");
insert(root, "Ortiz ", "584-3622");
Node nd = searchNodeIterativly(root, "Ortiz ");
if (nd == null) {
System.out.println("no result found!");
} else {
System.out.println(nd.name + ": " + nd.number);
}
}
}
最佳答案
长话短说,searchNodeIteratively
的逻辑看起来不错,但是 insert
被破坏,因为它构建了一个无效的树,并且类将从重写中受益。请继续阅读以了解详细信息。
这些类标榜核心 OOP 原则,最明显的违规行为是 re-use .如果 BinaryTree
中的所有逻辑类(class)是 hard coded依靠name
和 num
Node
的属性类,那么除了存储这两个确切的字段之外,它对于任何目的都是无用的,并且我们必须在数据更改时重新编写整个类。使用 generics , 我们可以允许 BinaryTree
或 Node
无需重写任何代码即可使用任意类型。
类(class)组织异常——BinaryTree
强制唯一性,所以它真的是 BinarySearchTree
类,并应相应命名。 insert
应该返回一个 boolean 值(无论插入是否成功)并且方法不应该是静态的。 new BinaryTree
在 main
被注释掉了,但这是正确的想法(我们要实例化一个 BST)。隐藏Node
BinaryTree
内部也很好(它是 BST 的实现细节),但它应该是私有(private)的。
其他备注:
.equals()
而不是 ==
比较对象,如 name == (Q.name)
; ==
比较内存位置(这可能是您的意图,但我会质疑这是否是我们认为独特的正确逻辑)。 Q
, P
Rlink
不要过多解释它们是什么,也不遵守 Java 变量命名约定(使用 lowerCamelCase)。除非含义很明显,否则避免使用单字母变量名称。 String num
不清楚-- String phoneNumber
更有意义。而不是写注释来解释不清楚的变量名称,如 Node P = null; // Parent of key to be inserted
,提供一个有意义的名称,如 Node parent = null;
并直接解决问题。 Ltag
和 Rtag
似乎是冗余信息,使插入逻辑非常困惑。只需检查左右Node
对象是 null
来测试它们的存在。这减少了膨胀并避免了 boolean 值与 Node
不同步的情况。值(value)观。 tmp.Llink = P.Llink;
tmp.Rlink = P;
tmp
) 的左链接设置为指向父节点的旧左链接,并将新节点的右链接指向父节点,从而打破了树的定义,即有一个根且没 Root过的图循环。 searchNodeIterativly
应该叫 searchNode
或 contains
.从这个类的客户的角度来看,它如何(迭代地)完成这一点应该是无关紧要的(这可能是私有(private)方法的适当名称)。 insert
不提供树的平衡,所以这基本上会削弱 contains
和 insert
方法复杂度为 O(n)。为树添加平衡将是一个很好的下一个添加,将操作带到所需的 O(n log(n))。 BinarySearchTree
中实现泛型和可重用性的初始重写。类(class)。我们可以调用
contains
使用 lambda 函数进行动态搜索(或者我们可以使用
T
的实例,如果这样更有意义的话)。这些类只部分实现了类契约——我希望
equals
和
hashCode
为初学者实现。
import java.util.*;
class BinarySearchTree<T extends Comparable<T>> {
public interface Comparator<T> {
int compare(T t);
}
private static class Node<T extends Comparable<T>>
implements Comparable<Node<T>> {
private T data;
private Node left;
private Node right;
Node(T data, Node left, Node right) {
this.data = data;
this.left = left;
this.right = right;
}
@Override
public int compareTo(Node<T> node) {
return this.data.compareTo(node.data);
}
}
private Node<T> root;
public BinarySearchTree() {
this.root = null;
}
public boolean insert(T item) {
Node<T> prev = null;
for (var curr = root; curr != null;) {
prev = curr;
if (curr.data.compareTo(item) == 0) {
return false;
}
curr = curr.data.compareTo(item) < 0 ?
curr.left : curr.right;
}
if (prev == null) {
root = new Node<T>(item, null, null);
}
else if (prev.data.compareTo(item) < 0) {
prev.left = new Node<T>(item, null, null);
}
else {
prev.right = new Node<T>(item, null, null);
}
return true;
}
public boolean contains(Comparator<T> cmp) {
for (var curr = root; curr != null;) {
if (cmp.compare(curr.data) == 0) {
return true;
}
curr = cmp.compare(curr.data) < 0 ?
curr.left : curr.right;
}
return false;
}
public boolean contains(T item) {
for (var curr = root; curr != null;) {
if (curr.data.compareTo(item) == 0) {
return true;
}
curr = curr.data.compareTo(item) < 0 ?
curr.left : curr.right;
}
return false;
}
private static void print(Node node, int depth) {
if (node != null) {
print(node.left, depth + 4);
for (int i = 0; i < depth; i++) {
System.out.print(" ");
}
System.out.println(node.data);
print(node.right, depth + 4);
}
}
public void print() {
print(root, 0);
}
}
class Person implements Comparable<Person> {
private String name;
private String phone;
public Person(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() { return name; }
public String getPhone() { return phone; }
public String toString() { return name; }
public int compareTo(Person person) {
return name.compareTo(person.name);
}
}
class Main {
public static void main(String[] args) {
String[][] data = {
{"Ikerd", "291-1864"},
{"Gladwin", "295-1601"},
{"Robson", "293-6122"},
{"Dang", "295-1882"},
{"Bird", "291-7890"},
{"Harris", "294-8075"},
{"Ortiz", "584-3622"},
{"Ortiz", "584-3622"}
};
var people = new BinarySearchTree<Person>();
for (var entry : data) {
people.insert(new Person(entry[0], entry[1]));
}
people.print();
System.out.println(
"\nContains \"Bird\"? " + people.contains((p) -> p.getName().compareTo("Bird"))
);
System.out.println(
"Contains \"Birds\"? " + people.contains((p) ->
p.getName().compareTo("Birds"))
);
}
}
Robson
Ortiz
Ikerd
Harris
Gladwin
Dang
Bird
Contains "Bird"? true
Contains "Birds"? false
关于java - 二叉树的搜索功能未返回找到的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58827282/
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我正在尝试将图像拖放到div上。图像没有被拖到div上并给出以下错误 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': pa
我正在 android studio 中创建内部构建 AR 导航。我正在寻找一种方法将 anchor 与其他 anchor 或 anchor 节点/节点“连接”起来。我不确定使用哪一个。基于我将强制用
我在 Hive 上运行一些作业:首先是 4 节点,然后是 2 节点。令我惊讶的是,我的 2 节点性能比我的 4 节点更好。 首先,我在一个 4 节点(4 个事件节点)上运行查询,然后关闭 2 个节点(
我有 Node* current ,我在其中存储指向列表“顶部”当前节点的指针。当我将一个新节点设置为当前节点时,出现错误: '=' : cannot convert from 'CircularDo
我是 dcos Mesos 的新手,在本地 Ubuntu 机器上安装了 dc os。 我可以查看 dcos 仪表板。 但我无法使用 dcos node ssh --master-proxy --lea
在 JavaFX 中,是否有类似 setLayout(); 的东西?或 setBounds(); ? 例如,我想将按钮定位到我想要的位置。 最佳答案 JavaFX 场景图上的所有内容都是 Node .
我正在开发一个 JavaFX 应用程序,其中我开发的类(从 javafx.scene.Parent 扩展)是根据用户在 ListView 控件中单击的条目动态创建的。 只是要清楚这个节点,它不是使用像
我正在尝试为节点-边缘关系创建一个类图,因为它可以在有向图中找到。我想传达的是,Nodes 引用了 Edges,Edges 也引用了 Nodes。每个 Edge 都恰好需要两个 Node(源和目标)。
在mapreduce作业期间,单个任务将在随机节点上运行,是否有任何方法限制应在其中运行任务的节点? 最佳答案 Hadoop不会选择节点来随机运行任务。考虑到数据局部性,否则将有很多网络开销。 任务与
有什么区别: a) nodetool 重建 b) nodetool 修复 [-pr] 换句话来说,各个命令到底是做什么的? 最佳答案 nodetool重建:类似于引导过程(当您向集群添加新节点时),但
我已将第一个 OneToMany 关系添加到我的 hibernate 3.6.10 项目中。这是一个类: /** * */ package com.heavyweightsoftware.leal
是否有可能找到正在监听触发当前函数的事件的元素? 在下面的代码中,event.target 返回 #xScrollPane 和 event.currentTarget 和 event 的最低子节点.f
我正在尝试覆盖我数据库中的一些数据。结构很简单,就是: recipes { user_1{ recipe_1{data} recipe_2{data} } user_2{
我使用 setInterval 来运行该函数,但它会多次执行函数 2... 如何在输入中插入一个值后执行函数 第一个输入与其余输入的距离不同 如何在插入 val(tab 选项)后将插入从 1 个输入移
我不知道代码有什么问题,但在 visual studio 中不断收到这些错误消息。 Error 18 error C1903: unable to recover from previous e
我正在尝试从其类中获取 SharePoint 搜索导航节点的对象。 var nodes = $("div.ms-qSuggest-listItem"); 我正在获取节点对象,现在想要获取“_promp
D:\nodeP>node main.js module.js:327 抛出错误; ^ 错误:在 Function.Module 的 Function.Module._resolveFilename
struct node{ int key, prior, cnt, val; node *l, *r; node(){} node(int nkey) : key(nkey),
我有以下代码使用迭代器将项目插入双链表。这就是我们被要求这样做的方式。代码有效,但问题是我有 24 字节的绝对内存泄漏。 NodeIterator insert(NodeIterator & itrP
我是一名优秀的程序员,十分优秀!