搜索树,修改不保存
Search Tree , modifications are not saving
我目前正在尝试使用搜索树来实现字典。 (练习告诉我使用这样的结构)。我的树由保存 2 个字符串的节点组成:abreviere(短语的缩写)和 acronim(短语)。到目前为止,这是我的实现:
节点Class:
public class Nod {
String acronim;
String abreviere;
Nod st,dr;
Nod(String acronim,String abreviere){
this.acronim = acronim;
this.abreviere = abreviere;
st = null;
dr = null;
}
}
树Class:
构造函数和插入:
public class Arbore {
Nod root;
Arbore(Nod x){
root = x;
}
public void insert(Nod x,Nod curr){
if(curr.acronim.compareTo(x.acronim) < 0){
if(curr.st == null){
curr.st = new Nod(x.acronim,x.abreviere);
}
else insert(x,curr.st);
}
else if(curr.dr == null){
curr.dr = new Nod(x.acronim, x.abreviere);
}
else insert(x,curr.dr);
}
}
我让他们工作。我不明白为什么我不能使用此代码:
public class Arbore {
Nod root;
Arbore(){
}
public void insert(Nod x,Nod curr){
if(curr == null) {curr = x; return;}
if(curr.acronim.compareTo(x.acronim) < 0){
if(curr.st == null){
curr.st = new Nod(x.acronim,x.abreviere);
}
else insert(x,curr.st);
}
else if(curr.dr == null){
curr.dr = new Nod(x.acronim, x.abreviere);
}
else insert(x,curr.dr);
}
这也不会保存我的结构(我显然遗漏了一些东西并且似乎是相关的)。我现在面临的问题是删除一个节点。我必须搜索一个缩写词 (abreviere),如果找到它,我必须打印该短语并删除该节点。这些是我用来执行此操作的方法:
public void search(String acronim){
if(root.acronim.compareTo(acronim) == 0) delete(root);
if(root.acronim.compareTo(acronim) < 0) search(acronim,root.st);
if(root.acronim.compareTo(acronim) > 0) search(acronim,root.dr);
}
private void search(String acronim,Nod curr){
if(curr == null){System.out.println("Nu exista"); return;}
if(curr.acronim.compareTo(acronim) == 0) this.delete(curr);
if(curr.acronim.compareTo(acronim) < 0) this.search(acronim,curr.st);
if(curr.acronim.compareTo(acronim) > 0) this.search(acronim,curr.dr);
}
private void delete(Nod x){
if(x.st == null && x.dr == null){ x = null; System.out.println("deleting");}
else if(x.st == null && x.dr != null) {x = x.dr;System.out.println("deleting right");}
else if(x.st != null && x.dr == null) {x = x.st;System.out.println("deleting left");}
else{
System.out.println("Il deletez");
Nod aux = new Nod(x.acronim,x.abreviere);
x.abreviere = x.st.abreviere;
x.acronim = x.st.acronim;
x.st.abreviere = aux.abreviere;
x.st.acronim = aux.acronim;
delete(x.st);
}
}
他们似乎在做这项工作(从打印的消息来看)。但是,更改不会保存,在我应用该方法后,我只剩下同一棵树。这是显示当前树的打印方法:
public String inordine(Nod root){
if(root == null) return "";
return inordine(root.st) + afis(root) + inordine(root.dr);
}
private String afis(Nod n){
if(n == null) return "E nula?!";
return n.abreviere + "->" + n.acronim + "\n";
}
public void afisare(){
System.out.println(inordine(this.root));
}
我做错了什么?是垃圾收集器还是什么?我这样使用 class:
public static void main(String[] args) throws FileNotFoundException, IOException {
FileReader fr = new FileReader("Acronime.txt");
BufferedReader bf = new BufferedReader(fr);
String line = bf.readLine();
String[] array = line.split("=>");
Nod x = new Nod(array[0],array[1]);
Arbore a = new Arbore(x);
while((line = bf.readLine()) != null){
String[] array2 = line.split("=>");
Nod y = new Nod(array2[0],array2[1]);
a.insert(y,a.root);
}
a.afisare();
a.search("JSE");
a.afisare();
}
话是这样来的,但这部分有效。
JSE=>JavaScript Encoding
ESP=>Enhanced Serial Port
MSB=>Most Significant Byte
CDRAM=>Cached Dynamic RAM
EMI=>Electro-Magnetic Interference
CDRAM=>Cached Dynamic RAM
AIFF=>Audio Interface File
BASM=>Built in AsseMbler
看了建议后 post 我在删除方法中更改了 2 行并添加了 1 个方法:
更改的行:
else if(x.st == null && x.dr != null) {copy(x,x.dr); x.dr = null; System.out.println("deleting right");}
else if(x.st != null && x.dr == null) {copy(x,x.st); x.st = null; System.out.println("deleting left");}
通过这种方式,更改得以保留(如果您想知道为什么,请阅读下面建议的 post 中的问题)。
最后的问题是:"How to delete an instance of a class because you can't do it with x = null;? "
关于构造函数:
在您要使用的方法(使用空构造函数)中,您需要在某个时候设置 class 成员 root
。应该这样做:
public void insert(Nod x,Nod curr){
if(curr == null) {
this.root = x;
return;
}
...
关于删除
我不明白 st 和 dr 不为空的情况。您似乎保持树结构完整,但切换 st 端的有效负载数据(abreviere,acronim),然后删除 st 节点。我还不明白。当我更好地理解时,我会更新我的答案。
您不能像我在删除方法 if(x.st == null && x.dr == null){ x = null;}
中尝试做的那样在 java 中销毁 class 的实例。要从树中删除节点,您必须找到 x 的父节点,然后 parent.x = null。这样 x 的引用就丢失了,垃圾收集器完成了他的工作。
这是因为,正如@Seelenvirtuose 所说,java 使用按值传递,您可以在他提供的 link 中阅读更多相关信息:click!
我目前正在尝试使用搜索树来实现字典。 (练习告诉我使用这样的结构)。我的树由保存 2 个字符串的节点组成:abreviere(短语的缩写)和 acronim(短语)。到目前为止,这是我的实现:
节点Class:
public class Nod {
String acronim;
String abreviere;
Nod st,dr;
Nod(String acronim,String abreviere){
this.acronim = acronim;
this.abreviere = abreviere;
st = null;
dr = null;
}
}
树Class:
构造函数和插入:
public class Arbore {
Nod root;
Arbore(Nod x){
root = x;
}
public void insert(Nod x,Nod curr){
if(curr.acronim.compareTo(x.acronim) < 0){
if(curr.st == null){
curr.st = new Nod(x.acronim,x.abreviere);
}
else insert(x,curr.st);
}
else if(curr.dr == null){
curr.dr = new Nod(x.acronim, x.abreviere);
}
else insert(x,curr.dr);
}
}
我让他们工作。我不明白为什么我不能使用此代码:
public class Arbore {
Nod root;
Arbore(){
}
public void insert(Nod x,Nod curr){
if(curr == null) {curr = x; return;}
if(curr.acronim.compareTo(x.acronim) < 0){
if(curr.st == null){
curr.st = new Nod(x.acronim,x.abreviere);
}
else insert(x,curr.st);
}
else if(curr.dr == null){
curr.dr = new Nod(x.acronim, x.abreviere);
}
else insert(x,curr.dr);
}
这也不会保存我的结构(我显然遗漏了一些东西并且似乎是相关的)。我现在面临的问题是删除一个节点。我必须搜索一个缩写词 (abreviere),如果找到它,我必须打印该短语并删除该节点。这些是我用来执行此操作的方法:
public void search(String acronim){
if(root.acronim.compareTo(acronim) == 0) delete(root);
if(root.acronim.compareTo(acronim) < 0) search(acronim,root.st);
if(root.acronim.compareTo(acronim) > 0) search(acronim,root.dr);
}
private void search(String acronim,Nod curr){
if(curr == null){System.out.println("Nu exista"); return;}
if(curr.acronim.compareTo(acronim) == 0) this.delete(curr);
if(curr.acronim.compareTo(acronim) < 0) this.search(acronim,curr.st);
if(curr.acronim.compareTo(acronim) > 0) this.search(acronim,curr.dr);
}
private void delete(Nod x){
if(x.st == null && x.dr == null){ x = null; System.out.println("deleting");}
else if(x.st == null && x.dr != null) {x = x.dr;System.out.println("deleting right");}
else if(x.st != null && x.dr == null) {x = x.st;System.out.println("deleting left");}
else{
System.out.println("Il deletez");
Nod aux = new Nod(x.acronim,x.abreviere);
x.abreviere = x.st.abreviere;
x.acronim = x.st.acronim;
x.st.abreviere = aux.abreviere;
x.st.acronim = aux.acronim;
delete(x.st);
}
}
他们似乎在做这项工作(从打印的消息来看)。但是,更改不会保存,在我应用该方法后,我只剩下同一棵树。这是显示当前树的打印方法:
public String inordine(Nod root){
if(root == null) return "";
return inordine(root.st) + afis(root) + inordine(root.dr);
}
private String afis(Nod n){
if(n == null) return "E nula?!";
return n.abreviere + "->" + n.acronim + "\n";
}
public void afisare(){
System.out.println(inordine(this.root));
}
我做错了什么?是垃圾收集器还是什么?我这样使用 class:
public static void main(String[] args) throws FileNotFoundException, IOException {
FileReader fr = new FileReader("Acronime.txt");
BufferedReader bf = new BufferedReader(fr);
String line = bf.readLine();
String[] array = line.split("=>");
Nod x = new Nod(array[0],array[1]);
Arbore a = new Arbore(x);
while((line = bf.readLine()) != null){
String[] array2 = line.split("=>");
Nod y = new Nod(array2[0],array2[1]);
a.insert(y,a.root);
}
a.afisare();
a.search("JSE");
a.afisare();
}
话是这样来的,但这部分有效。
JSE=>JavaScript Encoding
ESP=>Enhanced Serial Port
MSB=>Most Significant Byte
CDRAM=>Cached Dynamic RAM
EMI=>Electro-Magnetic Interference
CDRAM=>Cached Dynamic RAM
AIFF=>Audio Interface File
BASM=>Built in AsseMbler
看了建议后 post 我在删除方法中更改了 2 行并添加了 1 个方法:
更改的行:
else if(x.st == null && x.dr != null) {copy(x,x.dr); x.dr = null; System.out.println("deleting right");}
else if(x.st != null && x.dr == null) {copy(x,x.st); x.st = null; System.out.println("deleting left");}
通过这种方式,更改得以保留(如果您想知道为什么,请阅读下面建议的 post 中的问题)。
最后的问题是:"How to delete an instance of a class because you can't do it with x = null;? "
关于构造函数:
在您要使用的方法(使用空构造函数)中,您需要在某个时候设置 class 成员 root
。应该这样做:
public void insert(Nod x,Nod curr){
if(curr == null) {
this.root = x;
return;
}
...
关于删除
我不明白 st 和 dr 不为空的情况。您似乎保持树结构完整,但切换 st 端的有效负载数据(abreviere,acronim),然后删除 st 节点。我还不明白。当我更好地理解时,我会更新我的答案。
您不能像我在删除方法 if(x.st == null && x.dr == null){ x = null;}
中尝试做的那样在 java 中销毁 class 的实例。要从树中删除节点,您必须找到 x 的父节点,然后 parent.x = null。这样 x 的引用就丢失了,垃圾收集器完成了他的工作。
这是因为,正如@Seelenvirtuose 所说,java 使用按值传递,您可以在他提供的 link 中阅读更多相关信息:click!