find successor in AVL tree - java

there is avl tree with nodes, and each node has only 3 fields:
1.right child
2.left child
3.value(key)
notice that it doesnt have such field "parrent" or "father".
my question is: in case we want to know the successor of EVERY node in the tree,
and without use any LinkedList or any collection, what is the method to do so?

You could do something like this
// Returns the last node in the inorder traversal of tree,
// or prev if tree is null.
Node printSuccessors(Node tree, Node prev) {
if (tree == null) {
return prev;
}
Node lastLeft = printSuccessors(tree.leftChild(), prev);
if (lastLeft != null) {
System.out.println("The successor of " + lastLeft.key()
+ " is " + tree.key());
}
return printSuccessors(tree.rightChild(), tree);
}
and then call printSuccessors(root, null).

Related

Implementing my own LinkedList, insertion of a new element to the Tail doesn't work correctly

I`m trying to implement my own linkedlist and I tackled with this question.
This is add method implementation for linkedlist, supposed to add specified elements to the end of the list.
Below you see a code I found and that works, and you see my code which only shows last 2 elements added no matter how many you add to the list.
The only difference 2 codes have is that he stores rootNode (head) inside currentNode and does his traversing using currentNode. I directly used rootNode to do the same. Can someone explain my what is wrong with my code ?
This is his code that works:
public void add (E val) {
Node newNode = new Node(val, null);
Node currentNode = rootNode;
if (rootNode == null) {
rootNode = newNode;
} else {
while (currentNode.nextNode != null) {
currentNode = currentNode.nextNode;
}
currentNode.setNextNode(newNode);
}
}
And this is my code that only shows last 2 elements added :
public void add (E val) {
Node newNode = new Node(val, null);
if (rootNode == null) {
rootNode = newNode;
} else {
while (rootNode.nextNode != null) {
rootNode = rootNode.nextNode;
}
rootNode.setNextNode(newNode);
}
}
That happens because you're resigning the rootNode while iterating.
By making this, you are erasing all previous state of the list, which you can access only via root. That's way the only node that remain in the list are root and its next node.
In order to iterate over the list, you should introduce the local variable like in the first version. There's no other way around.
And I suggest to simplify the method a bit by returning after checking whether the root is null, there will be no in nesting the loop into the additional block of curly braces:
public void add (E val) {
Node newNode = new Node(val,null);
if(rootNode == null) {
rootNode = newNode;
return;
}
Node currentNode = rootNode;
while (rootNode.nextNode != null) {
rootNode = rootNode.nextNode;
}
rootNode.setNextNode(newNode);
}
Because you are changing root node, after add method ends, you have only the root node and the next node of it, do not change root node if it is not null.
For instance, you call add Method for nodes A, B, and C.
For the first time root is A, then when you call add(B), as the root node is not null already, loop will not work in the else statement and the next of A will be B, then when you call add(C), while loop will work one iteration and B will become root node(you lost A) and the next of B will be C node.

Put the post-order traversal values in an arraylist

On the web there is the solution for printing the values, like this:
void printPostorder(Node node)
{
if (node == null)
return;
// first recur on left subtree
printPostorder(node.left);
// then recur on right subtree
printPostorder(node.right);
// now deal with the node
System.out.print(node.key + " ");
}
But my problem is that I don't want to print the values but put them in an ArrayList. That part is easy I've tried to use ArrayList.add instead of System.out.print, but my struggle is that I want to return it so instead of void my return type will be ArrayList. The problem is that I don't know what to return in the base case:
if (node == null)
return;
My method does return an ArrayList so what can I return for the base case above?
In the end case you could return an empty list, and accumulate the results by calling addAll:
List<Node> getPostOrderList(Node node) {
List<Node> retVale = new ArrayList<>();
if (node == null) {
return retVal;
}
// first recur on left subtree
retVal.addAll(getPostOrderList(node.left));
// then recur on right subtree
retVal.addAll(getPostOrderList(node.right));
// now deal with the node
retVal.add(node);
return retVal;
}

BFS on a tree with lists

So I'm building this tree which has 1..* Nodes where each node has a list which in themselves can have 1..* nodes.
The first three levels of the tree I can build just fine but then it won't work more if I don't code all the levels which are just plain stupid. The solution is of course to use some kind of recursive method and a BFS.
Basically, in my TreeBuilder class, I want to be able to call tree.getNodesAtDepth(depth)) and get a list of all nodes that are at that depth. Problem is that I don't understand how I can implement the getNodesAtDepth(depth) method.
All the examples I find are for binary trees. An alternative is to have the addChild method take a depth argument so I can specify at which depth to insert the child at.
In the end, this is what I want:
I have a tree with a root. The root has a list which has 4 children nodes. I want to get the 4 children. For each child generate three nodes. So for child 0 has 3 children, child 1 has 3 children, child 3 has 3 children and child 4 has 3 children. And so forth
Maybe a possible soultion is to have a level attribute on each node and search for that node and then return it's parent. Beacuse it's parent should have a list of all the nodes at the searched for node.
Try this method :
static void getNodesAtDepth(Node root, int currentLevel, int level, List<Node> nodes) {
if(root == null) return;
if(level == 0) {
nodes.add(root);
return;
}
if(currentLevel + 1 == level) {
if(root.getNodeList() != null) {
nodes.addAll(root.getNodeList());
}
}
if(currentLevel < level) {
if(root.getNodeList() != null) {
for(Node node : root.getNodeList()) {
getNodesAtDepth(node, currentLevel + 1, level , nodes);
}
}
}
}
How to use it :
List<Node> nodeList = new LinkedList<>();
getNodesAtDepth(root, 0, 2, nodeList);
root of course is the root of your tree. nodeList will store all your nodes at desired level (in my case it's 2). Second parameter is always 0, (that's for keeping track of the current level)
If I assume your class tree structure is :
class Tree {
List<Tree> children
...
}
Then you can recursively iterate through the tree until you find the expected depth:
void recursivelyCollectNodesAtDepth(int depth,
List<Tree> nodesAtDepth,
Tree tree,
int currentDepth) {
if (tree == null) {
return;
}
if (depth == 0) {
nodesAtDepth.add(tree);
} else if (currentDepth + 1 == depth) {
// add children to the node list when expected depth is reached
if (tree.getChildren() != null) {
nodesAtDepth.addAll(tree.getChildren());
}
} else if (currentDepth < depth) {
// iterate and recursively travers through child nodes
for (Tree childTree : tree.getChildren()) {
recursivelyCollectNodesAtDepth(depth,
nodesAtDepth,
childTree,
currentDepth + 1);
}
}
}
Here the tree nodes a recursively traversed to the expected level

Linked lists - Can't figure out why this remove last function is not working?

I made this remove last function and it seems like it should work, but when I call it, it doesn't actually remove anything, all of the nodes are still there.
Is there any problem with it?
public Object removeLast()
{
Node currentNode;
currentNode = this.getHead();
while(currentNode != null)
{
if(currentNode.getNext()==null)
{
currentNode = null;
return null;
}
currentNode = currentNode.getNext();
}
return null;
}
You have a list which contains nodes. Each node contains a pointer to the next node.
To remove a node from the list, you have to set the next pointer of the previous node to null
If you also have a pointer to the previous element, this is trivial. Something like:
public Object removeLast()
{
Node currentNode;
currentNode = this.getHead();
while(currentNode != null)
{
if(currentNode.getNext()==null)
{
// The line below is changed!!!
currentNode.getPrevious().setNext(null);
return null;
}
currentNode = currentNode.getNext();
}
return null;
}
If you have a pointer in each node to the next as well as the previous node, then we call this a doubly-linked-list.
Also, there's no need for the return type to be Object, you can change your method signature to:
public void removeLast()
And then change each of your return null; to return;
What you do now is that you set your dummy node to null, but that does not effect your list at all. I'll try to visualize:
Your original list consists of nodes, connected by next-pointers. The local variable currentnode refers to one of the nodes in the list. Below, it points to the last element.
head --<next>-> node --<next>-> node --<next>-> node --<next>-> null
^
|
currentnode
If you now do currentnode = null, this yields:
head --<next>-> node --<next>-> node --<next>-> node --<next>-> null
currentnode --> null
Note that this does not affect your linked list at all.
What you want to do instead is set the --<next>-> of the one-but-last node to null. For this, you should keep track of the previous node while iterating your list:
if (getHead().getNext() == null) {
setHead(null);
} else {
Node previous = getHead();
Node current = previous.getNext();
while (current.getNext() != null) {
previous = current;
current = current.getNext();
}
previous.setNext(null);
}

given a node how can I find previous node in a singly linked list

Given the current node, how can I find its previous node in a Singly Linked List. Thanks. Logic will do , code is appreciated. We all know given a root node one can do a sequential traverse , I want to know if there is a smarter way that avoids sequential access overhead. (assume there is no access to root node) Thanks.
You can't.
Singly-linked lists by definition only link each node to its successor, not predecessor. There is no information about the predecessor; not even information about whether it exists at all (your node could be the head of the list).
You could use a doubly-linked list.
You could try to rearrange everything so you have the predecessor passed in as a parameter in the first place.
You could scan the entire heap looking for a record that looks like a predecessor node with a pointer to your node. (Not a serious suggestion.)
If you want to delete the current node, you can do that without finding previous node as well.
Python Code:
def deleteNode(self, node):
node.val = node.next.val
node.next = node.next.next
# Delete Node in a Linked List
Walk through the list from the beginning until you meet a node whose next link points you your current node.
But if you need to do this, perhaps you oughtn't be using a singly linked list in the first place.
Your only option for a singly-linked list is a linear search, something like below (Python-like pseudo code):
find_previous_node(list, node):
current_node = list.first
while(current_node.next != null):
if(current_node.next == node):
return current_node
else:
current_node = current_node.next
return null
Assuming that you're talking about a forward singly linked list (each node only has a pointer to 'next' etc) you will have to iterate from the start of the list until you find the node that has 'next' equal to your current node. Obviously, this is a slow O(n) operation.
Hope this helps.
Keep two-pointer(curr, prev) initially both will point to head of the list.
do a loop on the list until you either reach at the end of the list or at the required node.
for each iteration move curr node to the next of it but before moving to next store its pointer in prev pointer.
prev = curr; // first store current node in prev
curr = curr->next // move current to next
at the end of loop prev node will contain previous node.
getPrev(head, key) {
Node* curr = head;
Node* prev = head;
while(curr !=null && curr->data==key){
prev = curr;
curr = curr->next
}
return prev
}
Example:
list = 1->5->10->4->3
We want prev node of 4 So key = 4 and head point at 1 here
initially:
temp will point to 1
prev will point to 1
iteration 1:
First, assign prev=temp (prev point to 1)
move temp; temp->next (temp point to 5)
iteration 2:
First, assign prev=temp (prev point to 5)
move temp; temp->next (temp point to 10)
iteration 3:
First, assign prev=temp (prev point to 10)
move temp; temp->next (temp point to 4)
iteration 4:
temp->data == key so it will return out of loop.
return prev node
This is some kind of hack which I found out while solving the problem(Delete every even node in a list)
internal void DeleteNode(int p)
{
DeleteNode(head, p);
}
private void DeleteNode(Node head, int p)
{
Node current = head;
Node prev = null;
while (current.next != null)
{
prev = current;
current = current.next;
if (current.data == p)
{
prev.next = current.next;
}
}
}
Now here, in prev you assign the current and then move the current to next thereby prev contains the previous node.
Hope this helps...
You can do it like this.. you can replace the value of current node by value of next node.. and in the next of 2nd last node you can put null. its like delete a element from a string. here is code
void deleteNode(ListNode* node) {
ListNode *pre=node;
while(node->next)
{
node->val=node->next->val;
pre=node;
node=node->next;
}
pre->next=NULL;
}
Use a nodeAt() method and pass the head,size and the index of the current node.
public static Node nodeAt(Node head,int index){
Node n=head;
for(int i=0;i<index;i++,n=n.next)
;
return n;
}
where n returns the node of the predecessor.
Here is a small trick with linear search: just pass in the node or its position whose previous node you are searching for:
private MyNode findNode(int pos) {
//node will have pos=pos-1
pos-- = 1;
MyNode prevNode = null;
int count = 0;
MyNode p = first.next; // first = head node, find it however you want.
//this is for circular linked list, you can use first!=last for singly linked list
while (p != first) {
if (count == pos) {
prevNode = p;
break;
}
p = p.next;
count++;
}
return prevNode;
}
We can traverse through the LinkedList using slow and fast pointers.
Let's say
fast pointer fast = fast.next.next
slow pointer slow = slow.next
Slow pointer will be always a previous of the fast pointer, and so we can able to find it.
It can possible to deleteNode if only given node not root or head. How ?
It can achieve by reversing value in node
4-> 2 -> 1 -> 9 given 2 as node to remove. as above other can't access previous node which is correct because singly linked list we don't store predecessor. What can do is swap value of next of give node to given node and change link to next of next of give node
nextNode = node.next // assigning given node next to new pointer
node.val = nextNode.val // replacing value of given node to nextNode value
node.next = nextNode.next // changing link of given node to next to next node.
I tried this approach and its working fine.
assuming you are using forward singly linked list your code should look like
while(node)
{
previous = node
node = node.next
// Do what ever you want to do with the nodes
}

Categories