我一直在尝试学习一些数据结构的细节,我试图让二进制splay树正常工作。每次我运行下面的代码和我正在寻找的节点不止一个超过根,它告诉我它在那里,然后只是从根向下删除整个端。如果节点距离顶部只有一层,它可以正常工作。
我不确定会出现什么问题,但我认为这与我的旋转功能有关。我得到了正确的插入功能,这是我之后建模的。
public class SplayBST {
Node root;
int count;
int level = 0;
boolean found = false;
public SplayBST() {
root = null;
count = 0;
}
public String searchIt(String x) {
//after finishing search method I need to check if splaySearch exists then don't insert just splay it
splaySearch(root, x);
if (this.found == true) {
this.found = false;
return x;
}
else {
return null;
}
}
Node splaySearch(Node h, String x) {
if (h == null) {
return null;
}
if (x.compareTo(h.value) < 0) {
try {
if (x.compareTo(h.left.value) < 0) {
h.left.left = splaySearch(h.left.left, x);
h = rotateRight(h);
} else if (x.compareTo(h.left.value) > 0) {
h.left.right = splaySearch(h.left.right, x);
h.left = rotateLeft(h.left);
}
else {
this.found = true;
return h.left;
}
return rotateRight(h);
}
catch (NullPointerException ex) {
return null;
}
}
else { //basically x.compareTo(h.value)>0
try {
if (x.compareTo(h.right.value) > 0) {
h.right.right = splaySearch(h.right.right, x);
h = rotateLeft(h);
} else if (x.compareTo(h.right.value) < 0) {
h.right.left = splaySearch(h.right.left, x);
h.right = rotateRight(h.right);
}
else {
this.found = true;
return h.right;
}
return rotateLeft(h);
}
catch (NullPointerException ex) {
return null;
}
}
}
Node rotateLeft(Node h) {
Node x = h.right;
h.right = x.left;
x.left = h;
return x;
}
Node rotateRight(Node h) {
Node x = h.left;
h.left = x.right;
x.right = h;
return x;
}
class Node {
Node left;
Node right;
String value;
int pos;
public Node(String x) {
left = null;
right = null;
value = x;
}
}
}
答案 0 :(得分:2)
我的第二个特里斯坦赫尔的方法是用#34;工作&#34;创建一个常规的BST。搜索方法。一旦你开始工作,添加一个splay方法就相当简单了。当我实施Splay Tree in Java时,我实际上做了同样的事情。它是一种更好的软件设计和更简单的实现。
答案 1 :(得分:1)
您的问题是,在旋转时,您更新了“SplaySearch”函数中对节点H的引用,但是您没有更新原始“searchIt”函数中的父节点。因此,程序“认为”原始父节点仍然是父节点,即使旋转节点应该是父节点。因此,当您运行用于打印树的任何方法时,您从一个实际上不是树的父节点的节点打印,而是打印一个子节点(它所在的级别取决于您的程序调用rotateLeft和rotateRight的次数) )。
为了解决这个问题,我建议在普通的二叉树中实现搜索,然后将“splay”函数与将节点展开到树顶部的搜索函数完全分开。您可以在每次搜索结束时调用此展开功能,确保正确更新您的参考。这是实现splay树的传统方法,我建议你看看它(可能看一下关于splay树的维基百科文章或做Google搜索)。此外,您可能想知道旋转功能不完整。就展开树而言,您还有两种不同类型的双旋转,这与单次旋转非常不同。同样,我建议查看splay树,以便更深入地了解它们。