- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要在这个实现中写 successor 和 predecessor,但是我不知道没有 parent 怎么写。你可以建议如何最好地制作这些方法吗?这是我的 TreeNode 类
public class TreeNodee<K extends Comparable<K>> {
public K data;
int counter;
public TreeNodee<K> left, right;
public int height;
public int bf;
TreeNodee parent;
public TreeNodee(K data, TreeNodee parent) {
this.data = data;
counter = 1;
this.parent = parent;
}
public TreeNodee(K data) {
this.data = data;
counter = 1;
}
}
还有那个 AVL 树:
public class AVL<T extends Comparable<T>> {
private TreeNodee<T> root;
private int size;
public void add(T data) {
if (contains(data)){
root.counter++;
return;
}
TreeNodee<T> newNode = new TreeNodee<T>(data);
root = add(root,newNode);
size++;
}
public boolean contains(T data) {
if (isEmpty())return false;
return contains(root,data);
}
private boolean contains(TreeNodee<T> current, T n){
if(current==null)return false;
if(compare(current.data,n) == 0){
return true;
}
else{
if(contains(current.right,n)){return true;}
else if(contains(current.left,n)){return true;}
return false;
}
}
private TreeNodee<T> add(TreeNodee<T> current, TreeNodee<T> n){
if (current == null){
n.bf = 0;
n.height = 0;
return n;
}
if (compare(n.data,current.data)>0){
current.right = rotate(add(current.right,n));
}
else{
current.left = rotate(add(current.left,n));
}
current = rotate(current);
return current;
}
public T remove(T data) {
if(!contains(data)){
return null;
}
root = rotate(remove(root,data));
size--;
return data;
}
private TreeNodee<T> remove(TreeNodee<T> current, T n){
if (compare(current.data,n)==0){
if(current.right == null && current.left== null){
return null;
}
else if(current.right == null){
return rotate(current.left);
}
else if(current.left == null){
return rotate(current.right);
}
else{
TreeNodee<T> pre = current.left;
TreeNodee<T> predecessor;
if (pre.right==null){
predecessor = pre;
predecessor.right = current.right;
}
else{
while(pre.right.right!=null){
pre = pre.right;
}
predecessor = pre.right;
pre.right = predecessor.left;
predecessor.left = current.left;
predecessor.right = current.right;
}
return predecessor;
}
}
else{
if (compare(n,current.data)>0){
current.right = rotate(remove(current.right,n));
}
else{
current.left = rotate(remove(current.left,n));
}
return rotate(current);
}
}
private TreeNodee<T> updateHeightAndBF(TreeNodee<T> n) {
int left,right;
left = n.left!=null ? n.left.height : -1;
right = n.right!=null ? n.right.height : -1;
n.bf = left-right;
n.height = (right>left ? right : left) +1;
return n;
}
private TreeNodee<T> rotate(TreeNodee<T> n) {
if(n == null)return n;
n = updateHeightAndBF(n);
if(n.bf<-1){
if(n.right.bf>0){
n = rightLeft(n);
}
else{
n = left(n);
}
}
else if(n.bf>1){
if(n.left.bf<0){
n = leftRight(n);
}
else{
n = right(n);
}
}
return n;
}
private TreeNodee<T> left(TreeNodee<T> n) {
TreeNodee<T> newRoot = n.right;
TreeNodee<T> temp = n.right.left;
n.right.left = n;
n.right = temp;
n = updateHeightAndBF(n);
return newRoot;
}
private TreeNodee<T> right(TreeNodee<T> n) {
TreeNodee<T> newRoot = n.left;
TreeNodee<T> temp = n.left.right;
n.left.right = n;
n.left = temp;
n = updateHeightAndBF(n);
return newRoot;
}
private TreeNodee<T> leftRight(TreeNodee<T> n) {
n.left = left(n.left);
n = right(n);
return n;
}
private TreeNodee<T> rightLeft(TreeNodee<T> n) {
n.right = right(n.right);
n = left(n);
return n;
}
public boolean isEmpty() {
if (size==0) return true;
return false;
}
private int compare(T d1,T d2){
if (d1==null && d2 == null){
return 0;
}
else if(d1==null){
return 1;
}
else if(d2==null){
return -1;
}
else{
return d1.compareTo(d2);
}
}
}
最佳答案
不需要父链接。你只需要沿着树走下去,直到找到一片叶子。问题是“哪个叶子包含这个值的后继者/前任者?”
考虑到您在树中找到的节点,我将采用节点的直接前驱。另外,我会认为左 child 比当前节点小,右 child 比当前节点高。
现在,您已经有了自己的节点,您想要找到它的前任节点。 Predecessor 意味着您想要较小的最大节点。我们只看案例。
想象一下你的树是这棵树,你想要 3 的前身。很简单,这是他的父树:2。你可以用递归实现它,从树的根开始。你只需要跟踪下山途中遇到的最好的前任。
2
/ \
1 3
执行看起来像这样:
I'm at node 2, looking for the predecessor of 3 -> go right
I'm at node 3, looking for a predecessor of 3 -> go left
There's nothing, I didn't find any predecessor -> recursion rewinds
Crap, there is no predecessor found and 3 is not a predecessor of 3 -> recursion rewinds
Still no predecessor, but 2 is a predecessor of 3 -> recursion rewinds sending 2
Recursion ends: 2 is your value.
现在,如果您要查找其前任的节点没有左子树并且是其父节点的左子节点怎么办 -> 在递归过程中寻找他的祖父节点,直到找到一个更小的节点。
如果没有更小的节点怎么办?然后,这个节点实际上是树中最小的节点,他没有前任。
希望这是一个棘手的案例。现在,我们正在查看的节点有一个左子树。简单:前任隐藏在左子树的某处。好的是它是其中最大的节点(根据定义)。
所以你的前任是你左子树中最大的节点,这很容易找到 -> 向右走直到你碰到一片叶子。
继任者呢?相同,但相反。节点的后继是其右子树的最左边的叶子。同样,边缘情况是相同的,您可能正在寻找树中不存在的最大节点的后继节点。
为了实现这种操作,更容易完全放弃您正在处理 AVL 树的事实,只需考虑您将如何处理标准二叉树。
当你没有父指针时,你可以迭代:从根开始,在那些操作中始终考虑父、当前、左子和右子。事实上,这种方法通常更复杂,因为您需要同时跟踪很多节点。此外,您必须更新在每次迭代中找到的值,因为没有指针就没有上升。
我们倾向于递归地处理二叉树,因为结构本身是递归的。您可以通过一直传递它们来让父递归,但不是强制性的(这里它们不是必需的)。您只需要记住您是刚刚向您返回值的节点的父节点,并采取相应的行动。
这需要一些练习,但一旦您掌握了它,它就会相当直观。
关于java - AVL树,java,继任者,前任,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40131845/
相信维基百科文章:http://en.wikipedia.org/wiki/AVL_tree AVL trees are height-balanced, but in general not wei
我正在处理 AVL 树分配,我有一个关于它们定义的快速问题 - 我们得到了一个排序列表,我们必须在 O(n) 时间内从中生成一个 AVL 树。我已经完成了这个(感谢 StackOverflow 的其他
AVL 树与自平衡二叉搜索树相同。 AVL 代表什么?和发明者的名字有关系吗? 最佳答案 这是您猜到的发明者的名字。来自 wiki : AVL tree is named after its two
static String min ( AVLStringTreeNode t ) { if( t == null ) return t; while( t.left
一 点睛 平衡二叉查找树,简称平衡二叉树,由苏联数学家 Adelson-Velskii 和 Landis 提出,所以又被称为 AVL 树。 平衡二叉树或为空树,或为具有以下性质的平衡二叉树 1 左右子
更具体地说,是一个 AVL 树。是否可以?我想这样做,但我认为未删除的节点可能难以管理轮换。 我有一个可以正常工作的,但我想将这个带有延迟删除的用于其他用途。 最佳答案 如果您希望它相对于所有节点(包
更具体地说,如果使用 AVL 树而不是哈希表,是否可以更有效地执行任何操作? 最佳答案 我通常更喜欢 AVL 树而不是哈希表。我知道哈希表的预期时间 O(1) 复杂度优于 AVL 树的保证时间 O(l
我正在学习 AVL Tree 并在递归代码中获得了 TLE。我的导师建议迭代解决方案。我搜索并找到了一个将父节点保存在子节点中的解决方案。我想知道这个可能会在内存中出现问题,不是吗?还有另一种方法可以
据我所知AVL之间的时间复杂度树木和 Binary Search Trees在平均情况下是相同的,在最坏的情况下,AVL 会击败 BST。这给了我一个提示,即 AVL 在与它们交互的所有可能方式上总是
我正在用 C 语言实现 AVL 树。我在下面发布了我的树旋转,以及我在尝试测试它们时遇到的 valgrind 错误。 为什么我会收到这些错误?我知道 valgrind 错误源于我使用空指针这一事实,但
我试图理解以下 AVL 树的代码,但遇到了一些困难。我知道如果树很重,它就会向右旋转。同样,如果它是右重,它会向左旋转。如果有人能解释或指出我理解以下代码的正确方向,我将不胜感激。 static vo
我正在为 AVL 树编写右旋转。但它给出了运行时错误。目前我忽略了 AVL 树的高度部分。稍后我会处理这个问题。但是仅在 5 处应用右旋转就会出现问题。请帮助。我使用的AVL树是:
所以我有一个 C 语言的二叉搜索树代码,对我来说效果很好。但是,当我添加 BST 删除代码时,我的程序将在删除过程中崩溃。 它给我一个错误,提示访问冲突读取位置 0x00000000。 我认为这与传递
我正在为 AVL 树编写右旋转。目前我忽略了 AVL 树的高度部分。稍后我会处理这个问题。但是仅在 5 处应用右旋转会给出错误的值。即使执行右旋转后,l->data,ll->data,lll->dat
我在创建 AVL 树时遇到错误,我的代码的输出每次都给出无限循环。 在下面的代码中,mknode函数用于创建一个节点,lr,rl,right,leftfunctions用于执行所需的操作旋转,而插入函
我的 AVL 树是在 Java 中使用一个二维整数数组 avlTree[35][5] 实现的 - 列表示: [0] - 左侧高度 [1] - 左 child [2] - 数据 [3] - 右 chil
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 7 年前。 在第 7 行中,我得到 null
所以,我真的是编程新手,我现在正在上 C++ 类(class),我需要在其中编写和实现 AVL 树,使用双向链表打印树的内容,级别为等级。老师真的很挑剔,所以我们不能使用标准库中的任何容器。我的双向链
我被困在我的任务的一小部分,我基本上需要从 .txt 文件中插入数据(只是随机单词)并将它们作为数据添加到我的 AVL 树中。 我将向您展示我现在拥有的代码,该代码显然无法正常工作,但需要一些有关如何
我正在尝试用 Java 编写一个 AVL 树,并且已经在这个问题上停留了两个晚上。当运行以下代码时,肯定会发生旋转,但最终结果(例如 leftRotate)是我丢失了节点。 public AVLNod
我是一名优秀的程序员,十分优秀!