Red-black tree - How to find the node's parent?

≡放荡痞女 提交于 2019-12-22 11:23:44

问题


In red-black tree, when rotate, you need to know who is the parent of particular node. However, the node only has reference to either right or left child.

I was thinking to give a node instance variable "parent" but just for this reason I don't think it is worth doing so and also it would be too complicated to change parent reference per rotation.

public class Node {
  private left;
  private right;
  private isRed;
  private parent; //I don't think this is good idea
}

So, my solution is to write findParent() method that use search to find parent. I am wondering if there is any other way to find a node's parent?

My solution:

sample tree:

    50
    / \
   25  75

If you want to find parent of Node 25, you pass something like:

Node parent = findParent(Node25.value);

and it returns node50.

protected Node findParent(int val) {
        if(root == null) {
            return null;
        }
        Node current = root;
        Node parent = current;
        while(true) {
            if(current.val == val) { //found
                return parent;
            }
            if(current == null) { //not found
                return null;
            }
            parent = current;
            if(current.val > val) { //go left
                current = current.left;
            }
            else { //go right
                current = current.right; 
            }
        }
    }

回答1:


I was thinking to give a node instance variable "parent" but just for this reason I don't think it is worth doing so

Having your nodes have a parent reference requires one extra pointer/reference per node. Compare this with needing to traverse the tree whenever you need to know the parent for a given node.

This is then a trade-off between

  1. The cost of maintaining an extra reference, and keeping it up to date whenever you modify a node.
  2. The computational cost and complexity of having to traverse the tree to find a parent of a given node

I think that the choice between these two options is somewhat subjective but personally I would choose to simply keep track of the parent references.

As a point of reference for you, java.util.TreeMap is implemented as a Red-Black tree which Entry nodes that contain left, right, and parent references.




回答2:


As you traverse the tree to get to your pivot node you can cache the previous parent or if you need more than one level of "undo" you could cache each traversed node on to a stack.

This cache would be a variable local to your rotation algorithm so it wouldn't require any more space in the tree or expensive additional traversals.




回答3:


It's definitely better to store the parent than to look it up. Updating parent reference is not that complex.




回答4:


The use of a parent pointer is optional. If you forgo the parent pointer then you will have to write insert/delete operations using recursion (the recursive method calls preserve the parent information on the stack) or write an iterative version which maintains its own stack of parents as it moves down the tree.

A very good description of red-black trees can be found here

http://adtinfo.org/

That includes descriptions of a number of rbtree implementations including with and without parent pointers.

If you do want to save on space (and that is fair enough) a really excellent description of an rbtree implementation can be found here

http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx

The method you have described for searching for a node's parent would be very inefficient if used by the insert/delete implementations. Use a pointer or use recursion.




回答5:


Another solution, besides parent pointers and querying the parent all over again is to maintain an ancestor stack.

Suppose someone wishes to insert 23 into the following tree:

Red Black Tree

Generally the algorithm to insert is:

  1. Find node where 23 would be if it is in the tree

  2. If 23 is already there, return failure

  3. If 23 is not already there, put it there.

  4. Run your re-balancing/coloring routine as needed.

Now, to use the stack approach, you allocate a stack big enough to support one node per level of your tree (I think 2 * Ceiling(Log2(count)) + 2) should have you covered. You could even keep a stack allocated for insertion or deletion and just clear it whenever you start an insertion.

So -- Look at the root. Push it onto the stack. 23 is greater than value in the root, so go right. Now push node current node (value 21) onto the stack. If 23 is in the tree, it must be to the right of current node. But the node to the right of the current node is a null-sentinel. Thus, that null-sentinel should be replaced with a node with your value. The parent is the item on the top of the stack (most recently pushed), the grandparent is next in line ... etc. Since you seem to be learning ... Java supplies a stack interface for you so you won't need to develop your own stack to do this. Just use theirs.

As to whether this is better than the parent pointer approach, that seems debatable to me -- I would lean to the parent pointer approach for simplicity and elimination of the need to maintain an ancillary data structure or use recursion extensively. That said, either approach is better than querying the parent of the current node as you apply your re-balancing/coloring routine.



来源:https://stackoverflow.com/questions/3347018/red-black-tree-how-to-find-the-nodes-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!