Search Double Linked List Java Recursively - java

I am trying to search a doubly-linked list in Java for a term, and return it if found. Here is my code so far:
private class Node {
public String content;
public Node up;
public Node left;
public Node right;
}
private Node searchList(String term, Node node) {
while (node != null) {
System.out.print(node.name + " - "); //To see process
if (node.content.equals(term)) {
return node;
} else if (node.right != null) {
return searchList(term, node.right);
}
node = node.left;
}
return null;
}
My algorithm is basically:
While the node is not null
Check if it matches the search term
If there is an element to he right, scan that with recursion
Both points are now null, item is not present
Edit with my question, sorry:
I cannot get it to search down to bottom levels and having trouble understanding where I have gone wrong.
Any help would be appreciated!

I got to agree with the comments that your question is unclear.
However, I assume you are just looking for a way to implement a recursive search on a double linked list (in which null elements are not allowed). As the other answer already mentions, I assume type Page to be a subtype of Node. In fact, I will substitute it in my example below.
Since there seems to be some misconception about implementing a double linked list and about recursion itself, I will give a condensed but running example.
The code you are presenting lacks a termination condition for the recursion. Which, unfortunately, also holds true for ikicha's solution. One way (amongst others) to accomplish this is to use a helper method to pass an invariant (eg. the start element) or counter from one iteration of the recursion to the next one.
The line node = node.left in your example has no effect. If you wanted to achieve a search in both directions (as ikicha sketched) I would be interested in why direction matters for you.
public class DoubleLinked {
private Node first;
private Node last;
private int size;
private class Node {
public String content;
public Node left;
public Node right;
public Node(String content) {
this.content = content;
}
}
private void addElement(Node addedNode) {
if (first == null) {
first = addedNode;
last = addedNode;
} else {
last.right = addedNode;
addedNode.left = last;
addedNode.right = first;
last = addedNode;
}
size++;
}
private Node searchList(String term, Node node) {
int tries = 0;
if (node != null) {
return searchHelper(term, node.right, tries);
}
return null;
}
private Node searchHelper(String term, Node node, int tries) {
if (node == null || tries >= size) {
return null;
}
if (node.content.equals(term)) {
return node;
} else {
return searchHelper(term, node.right, tries);
}
}
public static void main(String[] args) {
DoubleLinked list = new DoubleLinked();
list.addElement(list.new Node("first"));
Node startNode = list.new Node("second");
list.addElement(startNode);
list.addElement(list.new Node("third"));
list.addElement(list.new Node("forth"));
Node r = list.searchList("forth", startNode);
System.out.println(r!=null?r.content:"term not found");
}
}

I think your algorithm computes same node several times because move left and find all right nodes of the left one repeatedly.
You can find node by search two direction each from start node.
private Node internalSearchList(String term, Node node, int direction) {
if (node == null) {
return null;
}
if (term.equals(node.content)) {
return node;
} else {
return internalSearchList(term, direction == 0 ? node.left : node.right, direction);
}
}
private Node searchList(String term, Node node) {
// search to left side
Node result = internalSearchList(term, node, 0);
if (result != null) {
return result;
} else {
return internalSearchList(term, node, 1);
}
}
And also I think the type of Node.left and Node.right must be Node.
private class Node {
public String content;
public Node up;
public Node left;
public Node right;
}

Related

Binary Search Tree: Remove TreeNode with given value x non recursively using Java

I am trying to write a non-recursive method that removes a node within a binary search tree if it contains the given input value int x in Java. I figured I need to use a stack but can't seem to figure out how to remove the node without calling the function on itself.
This is my TreeNode class as of now.
class TreeNode {
private int data; // data item (key)
private TreeNode left; // this node's left child
private TreeNode right; // this node's right child
// The "external node" is a special node that acts as a sentinel.
private final static TreeNode externalnode = TreeNode.createExternalNode();
/* Return a TreeNode that represents an "external node"*/
public static TreeNode getExternalNode() {
return externalnode;
}
/* Creates a new TreeNode with no children.
*/
public TreeNode(int id) { // constructor
data = id;
left = externalnode;
right = externalnode;
}
I have tried this but cant get it to work.
public TreeNode removeB(int x){
if (this == externalnode) return externalnode;
TreeNode one = new TreeNode(this.data);
System.out.println(this);
Stack<TreeNode> s = new Stack();
s.push(one);
//System.out.println(s);
boolean check;
boolean check1;
while(check = true){
if(x == one.left.data){
System.out.println(one.left.data);
check = false;
return one.left;
}
if(x == one.right.data){
System.out.println(one.right.data);
check1 = false;
return one.right;
}
}
Your code needs to first perform a binary search to find the node to remove. In pseudo-code, it looks something like:
while (currentNode != null && currentNode.value != target) {
if (currentNode.value > target) {
currentNode = currentNode.left;
} else if (currentNode.value < target) {
currentNode = currentNode.right;
}
}
Once you've targeted that node, you replace it with one of its children, and then graft in the other orphaned child under it, just as you would add any node.

Multiple the contents of the Nodes Linked List

I have a programming challenge that is to recursively multiple the data in the nodes of the list following it. For example
2 - 4 - 6 - 8
will be
384 - 192- 48 - 8
This is what I have done so far in the void product method. I keep getting a null pointer exception. What is wrong with my product method
class Node
{
private int data;
private Node next;
private Node prev;
public Node(int newData,Node newNext,Node newPrev)
{
data = newData;
next = newNext;
prev = newPrev;
}
public int getData()
{
return data;
}
public void setData(int otherData)
{
this.data = otherData;
}
public Node getNext()
{
return next;
}
public Node getPrev()
{ return prev;
}
public void setNext(Node newNext)
{
next = newNext;
}
public void setPrev(Node newPrev)
{
prev = newPrev;
}
}
class LinkedList
{
private Node head;
private Node start;
private Node end;
public LinkedList()
{
head = null;
start = null;
end = null;
}
public void insert(int data)
{
Node newNode = new Node(data,null,null);
if(start == null)
{
start = newNode;
end = start;
}
else
{
newNode.setPrev(end);
end.setNext(newNode);
end = newNode;
}
}
public void product()
{
product(head);
}
public void product(Node head)
{
Node next = head.getNext();
if(head == null)
{
return;
}
else
{
int data = head.getData() * next.getData();
head.setData(data);
product(head.getNext());
}
}
}
You are calling head.getNext() and next.getData() without checking if either of head or next is null, so the program will crash when processing the last node. Even so, you are only multiplying two consecutive items and not accumulating the product.
You can make use of the function's return value to accumulate the right answer:
public void product()
{
product(head);
}
public int product(Node head)
{
if(head == null)
{
return 1;
}
else
{
int data = head.getData() * product(head.getNext());
head.setData(data);
return data;
}
}
I didn't check the logic of your entire code, but the first thing that comes to mind is that you assign:
Node next = head.getNext();
And then you check if(head == null) but what about if(next == null)?
If it is, then you have your error right here:
next.getData()
Because head can be non-null, but its next can certainly be null.
The correct course of action would be to first check if(head == null), then assign Node next = head.getNext();, and then check if(next == null).
First, you call getNext() method on head and then you check if head is null? That is clearly wrong.
You should first check if head is null. Then you should check if next is null.
Also I don't think your recursion will compute the product correctly, since you multiply the data in your current head with what's currently in next - you could achieve that with a simple loop.
Instead you should call product(next) first and compute product later. Like this (didn't test it though)
public void product(Node head)
{
if (head == null)
return;
Node next = head.getNext();
product(next);
if (next != null)
{
int data = head.getData() * next.getData();
head.setData(data);
}
}

Convert Binary Search Tree to Doubly Linked List - not working

Solution i am pasting comes from this Geek URL
Its written in C, so i tried converting it in JAVA as below - (please do correct me if m wrong, i am not c/c++ person)
Program
// A simple recursive function to convert a given Binary tree to Doubly
// Linked List
// root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked list
public void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes head)
{
if(root == null)
return;
// Initialize previously visited node as NULL. This is
// declared outside the recursive function so that the same value
// is accessible in all recursive calls
prev = null;
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root.getLeft(), head);
//set head of LL if not set
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
head = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
Tree In Consideration
10
/ \
5 15
/ \ / \
2 7 12 18
/
1
/
0
Problem
This program returns output :
0 1 2 5 7 10 15 18
As you can see, 12 is missing from the code.I tried to dry run it many times but still not able to find out the real issue.....I tried searching for different solutions but most of them traverse in the part-converted-LL which increases the time complexity.
In original C code function prototype is following:
void BinaryTree2DoubleLinkedList(node *root, node **head)
**head mean double pointer, head value can be changed within function using *head. In java you can't modify function parameter because they are always copied, but you can modify array element.
So please try following code:
BTNode prev;
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes[] head)
{
// Base case
if (root == null) return;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(roor.getLeft(), head);
// Now convert this node
if (prev == null)
head[0] = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
Initial call should look like:
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
// result is in head[0]
To avoid ugly allocation for head element better to make additional function like following:
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
Converting Binary Search tree into Doubly Linked List is kind of easy task if we use left and right fields of Node.
Recursion helps us here.
First, go down till the left node. Assign the left most leaf node as prev and also as head of list.
Once control come back from leaf node to its parent, assign current node i.e. parent of left node as right of prev and left of current node as leaf node.
Same is goes for right leaf child of current node.
Once we are out of complete recursion, we will have our doubly linked list, with listHead and listTail.
{
Node prev = null;
Node listHead = null;
Node listTail = null;
public void convertToList(Node node)
{
if(node == null)
return;
convertToList(node.left);
if(listHead == null)
listHead = node;
if(prev == null)
prev = node;
else
{
node.left = prev;
prev.right = node;
}
prev = node;
convertToList(node.right);
if(node.right == null)
listTail = node;
}
public void printList()
{
Node node = listHead;
System.out.println("Doubly Linked List from Head: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.right;
}
}
public void printListFromTail()
{
Node node = listTail;
System.out.println("Doubly Linked List from Tail: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.left;
}
}
}
For any google visitor, i worked out a way to avoid head[0] - (this might pose problems if the program is called through different object for different trees, as head[0] may get overwritten)
Here is the implementation :
Trick is to remove prev = null; from the code and initialize tempHead = null and prev = null in the calling function, not in recursive call.
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes tempHead)
{
// Base case
if (root == null) return; //optional, not needed in fact
// Recursively convert left subtree
if(root.getLeft() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getLeft(), tempHead);
//set Original Head of the List, this would be leftmost
//leaf in the tree
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
tempHead = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
if(root.getRight() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getRight(), tempHead);
}
Other helper Details :
Initial call :
BinaryTree2DoubleLinkedList(bst.root,tempHead); //root and null value
Traverse List
printList(orgHead); //pass original head to print function
Complexity :
Time = Space : O(n)
public void ConverttoList(Node root){
Node top = root;
top.left = GetLeftNode(top.left);
top.right = GetRightNode(top.right);
top.left.right= top;
top.right.left= top;
Node leftmost = top.left;
while(leftmost.left!=null){
leftmost = leftmost.left;
}
while(leftmost!= null) {
System.out.printf(leftmost.Data + "->");
leftmost = leftmost.right;
}
}
public Node GetLeftNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node rightmost=root.right;
while (rightmost.right!=null){
rightmost=rightmost.right;
}
return rightmost;
}
}
public Node GetRightNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node leftmost=root.left;
while (leftmost.left!=null){
leftmost=leftmost.left;
}
return leftmost;
}
}
// bst to dll will generate a sorted dll
public class TreeToDLL {
public static void main(String args[]){
TreeNode t = new TreeNode(5);
TreeNode t3 = new TreeNode(3);
TreeNode t1 = new TreeNode(1);
TreeNode t7 = new TreeNode(7);
TreeNode t9 = new TreeNode(9);
TreeNode t8 = new TreeNode(8);
t.setLeft(t3);
t3.setLeft(t1);
t.setRight(t7);
t7.setRight(t9);
t9.setLeft(t8);
DllNode dll = convert(t);
dll.print();
}
static class DllNode{
int data;
DllNode next;
DllNode prev;
public DllNode(int data) {
this.data = data;
}
public DllNode() {
}
public int getData() {
return data;
}
public DllNode getPrev() {
return prev;
}
public void setPrev(DllNode prev) {
this.prev = prev;
}
public void setData(int data) {
this.data = data;
}
public DllNode getNext() {
return next;
}
public void setNext(DllNode next) {
this.next = next;
}
public void print(){
DllNode t = this;
while(t!=null){
System.out.print(t.getData()+"->");
t = t.getNext();
}
}
}
static class TreeNode{
int data;
TreeNode left;
TreeNode right;
public TreeNode(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public TreeNode getLeft() {
return left;
}
public TreeNode setLeft(TreeNode left) {
this.left = left;
return this;
}
public TreeNode getRight() {
return right;
}
public TreeNode setRight(TreeNode right) {
this.right = right;
return this;
}
}
private static DllNode convert(TreeNode t){
DllNode d =convert(t,new PreviousDLLNode());
while(d.prev!=null){
d = d.prev;
}
return d;
}
private static DllNode convert(TreeNode t, PreviousDLLNode d){
if(t==null) return null;
convert(t.getLeft(),d);
DllNode dn = new DllNode(t.getData());
if(d.val!=null){
d.val.setNext(dn);
}
dn.setPrev(d.val);
d.val = dn;
convert(t.getRight(),d);
return dn; // this node will be in the middle of the dll.
}
private static class PreviousDLLNode{
DllNode val;
}
}
I solved my problem inserting treenodes sorted in order in a DLL like that:
I added in my netBeans package the DoubleLinkedList and BinarySearchTree classes needed (including the TreeNode and the DoubleNode etc) and
I modified the BinarySearchTree as shown below:
public class BinarySearchTree {
DoubleLinkedList dL;
TreeNode root;
public BinarySearchTree() {
this.root = null;
this.dL=new DoubleLinkedList();
}
public void
tree2DList(TreeNode TN) {
if (TN == null) {
return ;
} else {
tree2DList(TN.left);
dL.insertLast((YourClassOfObjects)TN.getItem());
tree2DList(TN.right);
}
return;
}
I added a DoubleLinkedList field which I initialized in the default constructor of BST, calling the default constructor of DLL and I created the recursive method below, inspired from and following inOrderTraversal for the sorted input of tree nodes in the DLL

Occupied memory on a recursive call

I've started to learn about data structures at school and I have an homework where I have to implement an Binary Search Tree and tell the memory occupied by the data structures.
I've created my BST and I believe all is working as expected but I don't have a clue how to calculate the memory used.
This is the code I've created for the data structure and the code for inserting:
class Node {
int key, totalValue;
public Node left;
public Node right;
public Node (int key, int totalValue) {
this.key= key;
this.totalValue = totalValue;
this.left = null;
this.right = null;
}
public int getkey() {
return key;
}
public int getTotalValue() {
return totalValue;
}
}
class Tree {
private Node root;
public Tree() {
this.root = null;
}
public Node getRoot() {
return this.root;
}
public void setRoot(Node node) {
this.root = node;
}
}
And this is the code for inserting:
private static void addNode(Node node, Node tempNode) {
if (tempNode.getkey() < node.getkey()) {
if (node.left == null) {
node.left = tempNode;
} else {
addNode(node.left, tempNode);
}
} else if (tempNode.getkey() > node.getkey()){
if (node.right == null) {
node.right = tempNode;
} else {
addNode(node.right, tempNode);
}
}else{
node.totalValue += tempNode.getTotalValue();
}
}
I know that for each node I need 8 bytes for the 2 int, but I don't know how much each pointer occupies.
Second question. Imagine I insert 25000 entries from 10000 keys. Each insertion will be used recursively until the new node finds it's "position". How can I calculate the memory occupied?
The basic concept behind the recursive method would be
GetMemoryUsed(node)
{
if(node is leaf)
return (node.localMemory)
return(GetMemoryUsed(node.left) + GetMemoryUsed(node.right) + node.localMemory);
}
where node.localMemory is just the amount of memory that the specific node uses (not counting the child nodes)
As far as getting precise numbers, here are a couple of tools you might be interested in:
Java Instrumentation
JMap Memory Map

Inspect a Queue to print all elements

I am currently revising for my programming exam and I have came across a question from a past paper that has me rather confused.
I have two classes, Queue and Node, shown below.
The question states that I have to extend the behaviour of the Queue class by adding the necessary code to the inspectQueue method that prints to the console all the data stored within the queue.
The only solution I can think of, and it is very weak, is to have a simple ArrayList and every time an element is enqueued/dequeued then add/remove the node to/from the list.
Is there a better solution that I am glossing over? I'd really appreciate some guidance.
I've commented the code where I have implemented my "solution" the rest of the code is how it appears in the exam paper.
Thanks for your time.
Queue.java
public class Queue {
protected Node head;
protected Node last;
//added by me
private ArrayList<Node> nodes = new ArrayList<Node>();
//end my add
public boolean isEmpty() {
return (this.head == null);
}
public void enqueue(Object d) {
Node n = new Node();
n.setData(d);
nodes.add(n); //added by me
if (this.isEmpty()) {
head = n;
last = n;
}
else {
last.setNext(n);
last = n;
}
}
public Object dequeue() {
if(this.isEmpty()) {
this.last = null;
return null;
}
else {
Node h = this.head;
nodes.remove(h); //added by me
head = h.getNext();
return h.getData();
}
}
public Object peek() {
if(this.isEmpty()) {
return null;
}
else {
Node t = this.head;
return t.getData();
}
}
public void clearQueue() {
this.head = null;
this.last = null;
}
public void inspectQueue() {
//added by me (all below)
System.out.println("Inspecting Queue: (contains " + nodes.size() + " nodes)");
for(Node n : nodes) {
System.out.println(n.getData());
}
}
}
Node.java
public class Node {
protected Object data;
protected Node next;
public void setNext(Node e) {
this.next = e;
}
public Node getNext() {
return this.next;
}
public void setData(Object d) {
this.data = d;
}
public Object getData() {
return this.data;
}
}
Your nodes form a linked list, so just do
public void inspectQueue() {
Node n = head;
while (n != null) {
System.out.println(n.getData());
n = n.getNext();
}
}
This is a very basic data structure, called a LinkedList. In the your code for the Node class you can see the following:
protected Node next;
This means that every Node also holds a reference to the next Node in the list. If this Node is null, there are no more elements in the list. Knowing this, you can loop somewhat like this:
Node currentNode = this.head;
while(currentNode != null) {
System.out.println(currentNode.getData().toString());
currentNode = currentNode.getNext();
}
This eliminates the need for an ArrayList to store your references.
The LinkedList is a VERY frequently used data structure and very important to understand. If you have any questions, just go ahead and ask!
If you also want to have the size, keep a counter along, increment it each time you call getNext(), and print the size after the for loop.
You don't need the array, you have that information stored within the Node next property:
public void inspectQueue() {
Node current = head;
while(current != null) {
System.out.println(n.getData());
current = current.getNext();
}
}
That data structure is called linked list.
The simpler solution is to start with queue.head and traverse the linked list of nodes using node.next, printing the data as you go along.

Categories

Resources