Why am I getting false while doing search(7)?
I tried recursive solution its working fine..
tried implementing with loop failed
public class BST {
class Node {
int data;
Node left , right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
Node root;
public BST() {
this.root = null;
}
public void insert(int data) {
// create a new node and start iteration from root node
Node newNode = new Node(data);
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
currentNode = newNode;
break;
}
if (data < currentNode.data) { // if data is less go left
currentNode = currentNode.left;
} else if (data > currentNode.data) { // if data is greater go right
currentNode = currentNode.right;
} else { // do nothing for duplicates
break;
}
}
}
public boolean search(int data) {
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
return false;
}
if (data == currentNode.data) {
return true;
} else if (data < currentNode.data) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
public static void main(String... args) {
BST tree = new BST();
tree.insert(15);
tree.insert(7);
System.out.println(tree.search(7));
}
}
Problem is inside the insert method - you are not inserting the nodes correctly inside the tree.
If the tree is empty, you should assign to this.root, not currentNode. Assigning to currentNode has no affect on this.root.
Currently, your code isn't inserting any node inside the tree; it simply assigns the new node to the local variable of insert method, i.e. currentNode.
If the condition data < currentNode.data is true, then you need to check if the currentNode.left is null or not. If it is, then link the new node with the current node as shown below:
currentNode.left = newNode;
If currentNode.left is not null, then do the following:
currentNode = currentNode.left;
Currently, your code moves the currentNode to null and then assigns the newNode to the currentNode without a reference to its parent node in the tree.
Do step 2 for data > currentNode.data as well.
Change the implementation of the insert method as shown below:
public void insert(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
return;
}
Node currentNode = this.root;
while (true) {
if (data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
currentNode = currentNode.left;
}
} else if (data > currentNode.data) {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
currentNode = currentNode.right;
}
} else {
break;
}
}
}
Related
package linkedList;
import linkedList.Linkedlist.Node;
public class Linkedlist {
Node head = null;
Node tail = null;
class Node{
int data;
Node next;
Node (int data){
this.data = data;
this.next = null;
}
}
public void addNode(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
tail = newNode;
}else{
tail.next = newNode;
tail = newNode;
}
}
public void print() {
if(head == null) {
System.out.println("list is empty");
return;
}else {
Node disp = head;
while (disp !=null) {
System.out.print(disp.data+" ");
disp = disp.next;
}
}
System.out.println();
}
public void addFirst(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
return;
}else {
newNode.next = head;
head = newNode;
}
}
public void addLast(int data) {
Node newNode = new Node( data);
if(head == null) {
head = newNode;
return;
}else {
Node thisNode = head;
while(thisNode.next != null) {
thisNode = thisNode.next;
}
thisNode.next = newNode;
}
}
public void delete(int data) {
Node value = new Node(data);
if(head == null) {
head = value;
return;
}
Node temp = head;
if(data == 0 ) {
head =temp.next;
return;
}
for (int i = 0; temp != null && i < data - 1; i++) {
temp = temp.next;
if (temp == null || temp.next == null)
return;
Node next = temp.next.next;
temp.next= next;
}
}
public Node reverse(Node head)
{
Node prev = null;
Node current = head;
Node next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
public static void main(String[] args) {
Linkedlist a1 = new Linkedlist();
a1.addNode(200);
a1.addNode(300);
a1.addNode(400);
a1.addNode(500);
a1.print();
a1.addFirst(100);
a1.print();
a1.addLast(600);
a1.print();
a1.delete(5);
a1.print();
a1.reverse();
}
}
**how to call Node reverse method to main method...
when i try a1.reverse it show 3 option
head
-tail
-null
and all are show error.**
it is bassically input - 200 300 400 500
then add add 100 at head and 600 at tail
then delet the second position value
then reverse the linkedlist.
i try all methods but when i try to pass "Node head" parameter at reverse method and call it inside main method it show error .
I am having trouble figuring out how to set a variable "minData" to the minimum value inserted into a binary search tree. If I am thinking of this correctly, the most minimum value in the tree will always be in the left subtree so my code for setting this minimum value should go under the "else if (root.data < data)" statement. I also don't know how to access the minData variable inside my insert method. My code so far is:
private class Node {
int key;
int data;
int minData;
private Node left;
private Node right;
private Node root;
Node(int data) {
this.data = data;
left = null;
right = null;
root = null;
}
}
public TheBST(Node root) {
root = null;
}
public void insert(Node root, int data) {
Node newNode = new Node(data);
if(root == null) {
Node node = new Node(data);
root = node;
}
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
}
insert(root.left, data);
}
else if(root.data < data) {
if(root.right == null) {
Node node = new Node(data);
root.right = node;
return;
}
insert(root.right, data);
}
}
Your forming of BST is not accurately done. You need to return from the method (or stack fragment of memory in case recursive procedure) when you would actually find the place to insert.
Add the return statement for the left-subtree:
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
return;
}
insert(root.left, data);
}
Which is you are doing in case of the right-subtree.
P.S: once you are done with tree insertion, you can return the left-most-node from left-subtree, it would have the minimum value.
public class SearchLinkedList<E> {
private Node<E> first;
public static void main(String[] args){
SearchLinkedList<Integer> list = new SearchLinkedList<Integer>();
list.insert(1000);
list.insert(2000);
list.insert(3000);
System.out.println(list.getFirst());
}
public SearchLinkedList() {
first = null;
}
public void insert(E e) {
if (first == null) {
first = new Node<E>(e);
} else {
//while(temp.next.searched == true) then insert new Node where the next node is null or searched == false
Node<E> temp = new Node<E>(e);
temp.next = first;
first = temp;
}
}
public E getFirst() {
return first.data;
}
public E find(E x) {
if (first == null) {
return null;
} else {
//while (temp != null) if node found set it's searched = true and move it to front of list
Node<E> temp = first;
while (temp != null) {
if (temp.data.equals(x)) {
temp.searched = true;
return temp.data;
}
temp = temp.next;
}
return temp.data;
}
}
private static class Node<E> {
private E data;
private boolean searched;
private Node<E> next;
private Node(E e) {
data = e;
searched = false;
next = null;
}
}
}
So the assignment here is to create a LinkedList class that moves a node to the front of the list (first) if it has been searched.
First image here is when this is called:
list.insert(1000);
list.insert(2000);
list.insert(3000);
Second image is when this is called:
list.find(3000);
list.find(2000);
So the goal is when find is called and node with data is found: Set it's searched boolean to true and move that node to front of list. As of now, my insert just puts new node at the front of list. The comments in insert and find explain what I want to make them do. However, moving an element from the middle of a single linkedlist to front seems hard. Don't know what to do here. You can copy and try this yourself. After calling list.find(2000); and then list.getFirst() We should get 2000. Question is how... My thoughts are on if I should let the Node's booleans decide whether to be infront or not... Not sure here at all.
Thanks to danilllo19 for the help. That answer is correct only issue was that the new elements should be added from the front and so if an element is searched we're supposed to add the new one after the last searched but at the head of the un-serached ones. Solved it like this:
public void insert(E e) {
if(first == null){
first = new Node<E>(e);
}else{
Node<E> temp = first;
while(temp.searched && temp.next != null && temp.next.searched){
temp = temp.next;
}
Node<E> node = new Node<E>(e);
if(temp.searched && temp.next != null && !temp.next.searched){
Node<E> temp2 = temp.next;
temp.next = node;
node.next = temp2;
}else if(temp.searched && temp.next == null){
temp.next = node;
}else{
node.next = temp;
first = node;
}
}
}
I suppose you should do it like this:
public class SearchLinkedList<E> {
private Node<E> first;
public static void main(String[] args) {
SearchLinkedList<Integer> list = new SearchLinkedList<Integer>();
list.insert(1000);
list.insert(2000);
list.insert(3000);
System.out.println(list.getFirst());
System.out.println(list.find(3000));
System.out.println(list.getFirst());
list.insert(4000);
System.out.println(list.find(200));
}
public SearchLinkedList() {
first = null;
}
public void insert(E e) {
if (first == null) {
first = new Node<E>(e);
} else {
//while(temp.next.searched == true) then insert new Node where the next node is null or searched == false
Node<E> temp = first;
while (temp.next != null && temp.next.searched) {
temp = temp.next;
}
Node<E> node = new Node<>(e);
if (temp.next != null) {
node.next = temp.next;
}
temp.next = node;
}
}
public E getFirst() {
return first.data;
}
public E find(E x) {
if (first == null) {
return null;
} else {
//while (temp != null) if node found set it's searched = true and move it to front of list
Node<E> temp = first;
while (temp != null) {
if (temp.data.equals(x)) {
temp.searched = true;
break;
}
temp = temp.next;
}
if (temp == null) return null;
pushForward(temp);
return temp.data;
}
}
//Find pre-linked node with our node, bind our node with parent next node
//and link parent with node.
private void pushForward(Node<E> node) {
if (first == null || first.next == null) return;
Node<E> temp = first;
while (temp.next != null) {
if (temp.next.equals(node)) {
temp.next = temp.next.next;
node.next = first;
first = node;
break;
}
temp = temp.next;
}
}
private static class Node<E> {
private E data;
private boolean searched;
private Node<E> next;
private Node(E e) {
data = e;
searched = false;
next = null;
}
}
}
Also you could mix pushForward and find methods to make find to do what you want by one iteration through the list (O(n)), because O(n^2) there.
Might be helpful: https://www.geeksforgeeks.org/java-program-for-inserting-node-in-the-middle-of-the-linked-list/
I'm trying to implement priority queue using linked nodes, and I have all of my methods working correctly except for the add method. The purpose of the add method is to add a comparable object into the queue in the correct order. The order of the queue is as follows: the highest priority node is the firstNode. Any help as to what I'm doing wrong with my attempt would be much appreciated.
public void add(T newEntry) {
if(newEntry == null) {
return;
}
if(isEmpty()) {
firstNode = new Node(newEntry);
} else {
Node currentNode = firstNode;
if(newEntry.compareTo(firstNode.data)<0) {
firstNode = new Node(newEntry, firstNode);
length++;
return;
} else {
while(currentNode.getNextNode() != null && newEntry.compareTo(currentNode.next.data) > 0) {
currentNode = currentNode.next;
currentNode.setNextNode(new Node(newEntry, currentNode.getNextNode()));
}
}
}
length++;
return;
}
You have at least two problems, which I've pointed out in code comments:
public void add(T newEntry) {
if(newEntry == null) {
return;
}
if(isEmpty()) {
firstNode = new Node(newEntry);
} else {
Node currentNode = firstNode;
if(newEntry.compareTo(firstNode.data)<0) {
// Here you're assigning a new value to firstNode, but not linking to the old
// firstNode. So you're losing the entire list.
firstNode = new Node(newEntry, firstNode);
length++;
return;
} else {
while(currentNode.getNextNode() != null && newEntry.compareTo(currentNode.next.data) > 0) {
currentNode = currentNode.next;
// Here you're adding multiple new nodes to the list.
currentNode.setNextNode(new Node(newEntry, currentNode.getNextNode()));
}
}
}
length++;
return;
}
You can simplify that pretty easily:
public void add(T newEntry) {
if(newEntry == null) {
return;
}
Node newNode = new Node(newEntry);
if(isEmpty()) {
firstNode = newNode;
} else if (newNode.data < firstNode.data) {
// make newNode point to the firstNode,
// and then re-assign firstNode
newNode.setNextNode(firstNode);
firstNode = newNode;
} else {
Node currentNode = firstNode;
Node nextNode = currentNode.getNextNode;
while (nextNode != null && nextNode.data > newNode.data) {
currentNode = nextNode;
nextNode = currentNode.getNextNode;
}
// insert newNode between currentNode and nextNode
newNode.setNextNode(nextNode);
currentNode.setNextNode = newNode;
}
length++;
return;
}
So i have 3 methods 1 that adds a node to the binary tree using the traverseAdd method, and another method which finds the location of where a value would be placed within the tree based on its parent node. I would like to eliminate the traverseAdd method and use the findLocation method within the add method to add the new value to the BST.
public void add(int val) {
/*Adds a new node to the binary tree after traversing the tree and figuring out where it belongs*/
Node nodeObjToAdd = new Node(val);
if(root == null){
//if node root is not null root = new node value
root = nodeObjToAdd;
}
Node nodeTraversed = root;
traverseAdd(nodeTraversed, nodeObjToAdd);
}
private void traverseAdd(Node node, Node nodeObjToAdd){
/*Traverses tree and finds a place to add the node to be added by comparing values of the left child and right child of the
* focus node*/
if(nodeObjToAdd.value < node.value){
if(node.leftChild == null){
node.leftChild = nodeObjToAdd;
}
else {
//if the val < the root.value set int he constructor
traverseAdd(node.leftChild, nodeObjToAdd);
}
}
else if(nodeObjToAdd.value > node.value) {
if (node.rightChild == null) {
node.rightChild = nodeObjToAdd;
} else {
traverseAdd(node.rightChild, nodeObjToAdd);
}
}
}
public Node findNodeLocation(Node rootNode, int val) {
/*returns where a the Node after which the value would be added.*/
if(val < rootNode.value && rootNode.leftChild != null){
return rootNode.leftChild;
}
if(val >= rootNode.value && rootNode.rightChild != null){
return rootNode.rightChild;
}
else
return this.root;
}
public void add(int val) {
if (root == null) {
root = new Node(val);
}
Node cur = root;
Node next = null;
while (true) {
next = findNodeLocation(cur, val);
if (next != cur) {
cur = next;
} else {
break;
}
}
if (val < cur.value) {
cur.leftChild = new Node(val);
} else {
cur.rightChild = new Node(val);
}
}
I think this should work