Couldn't implement binary search on linked list - java

i am a cse student who takes data structures course. Trying to implement binary search algorithm to my SinglyLinkedList class, somehow i've failed. Could you check it what's wrong please ?
The related method;
I've debugged and it just enters the loops this side: else if(temp.getElement() > target)
public int binarySearchLinkedList(SinglyLinkedList<E> list, E target) {
int left = 0;
int right = list.getSize();
while (left <= right) {
int mid = (left + right) / 2;
Node<E> temp = head;
for (int i = 0; i < mid - 1; i++) {
temp = temp.next;
}
if (temp.getElement() instanceof Number && target instanceof Number) {
if (Integer.parseInt(temp.getElement().toString()) == Integer.parseInt(target.toString())) {
return mid;
} else if (Integer.parseInt(temp.getElement().toString()) > Integer.parseInt(target.toString())) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
All class for better understanding;
public class SinglyLinkedList<E> {
private static class Node<E> {
private E element;
private Node<E> next;
public Node(E e, Node<E> n) {
element = e;
next = n;
}
private E getElement() {
return element;
}
private Node<E> getNext() {
return next;
}
private void setNext(Node<E> n) {
next = n;
}
}
private Node<E> head;
private Node<E> tail;
private int size;
public SinglyLinkedList() {
};
public int getSize() {
return size;
}
public void append(E e) {
if (head == null) {
head = new Node<E>(e, null);
tail = head;
size++;
return;
}
Node<E> temp = head;
while (temp != tail) {
temp = temp.next;
}
temp.setNext(tail = new Node<E>(e, null));
size++;
return;
}
public int binarySearchLinkedList(SinglyLinkedList<E> list, E target) {
int left = 0;
int right = list.getSize();
while (left <= right) {
int mid = (left + right) / 2;
Node<E> temp = head;
for (int i = 0; i < mid - 1; i++) {
temp = temp.next;
}
if (temp.getElement() instanceof Number && target instanceof Number) {
if (Integer.parseInt(temp.getElement().toString()) == Integer.parseInt(target.toString())) {
return mid;
} else if (Integer.parseInt(temp.getElement().toString()) > Integer.parseInt(target.toString())) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
public String toString() {
StringBuilder sb = new StringBuilder();
Node<E> temp = head;
while (temp != tail) {
sb.append(temp.getElement()).append(", ");
temp = temp.next;
if (temp == tail) {
sb.append(temp.getElement());
}
}
return sb.toString();
}
}
And the main method;
public static void main(String[] args) {
SinglyLinkedList<Integer> list = new SinglyLinkedList<>();
list.append(10);
list.append(20);
list.append(30);
list.append(40);
list.append(50);
list.append(60);
list.append(70);
list.append(80);
list.append(90);
list.append(100);
System.out.println(list);
System.out.println(list.binarySearchLinkedList(list, 30));
}
It returns;
10, 20, 30, 40, 50, 60, 70, 80, 90, 100
-1

I'm guessing this line is the biggest issue:
for (int i = 0; i < mid - 1; i++) {
Consider what happens if mid is 1. The loop won't execute, because it is not the case that 0 < 1-1. So the inspected node won't be the one you think it is. The actual node at index mid will never be inspected. So the outer loop will eventually exit, never having found the target. Presumably your method ends with return -1;.
Other issues include:
You're initializing right to an exclusive value, but treat it as inclusive elsewhere. Consider using int right = list.getSize() - 1;
You've declared a generic method, but implemented it only for Integer. One way around this would be to limit the generic type to one that supports Comparable - e.g., E extends Comparable<E>.
You're implementing a binary search in a linked list. In a linked list, linear search would be simpler and no less efficient. Or you could use a data structure that supports constant-time access by index, such as an array or ArrayList.

Related

Swaping elements in likendlist for a few times java

I am trying to swap elements but the cycle is infinite.
The problem is in method change() or find().
I am just learning JAVA, so its hard to me to understand where is the mistake.
import java.util.*;
public class CustomLinkedList {
class Node{
int element;
Node next;
Node(int element){
this.element = element;
}
}
private Node first;
private Node last;
private int size;
private Node temp;
public void add(int element) {
Node newNode = new Node(element);
if(first == null) {
first = last = newNode;
} else {
last.next = newNode;
last = newNode;
}
size++;
}
public void output() {
Node current = first;
if(current == null) {
System.out.println("YOUR LIST IS EMPTY!!! ADD SOME ELEMENTS!!!");
}
else {
while(current != null) {
System.out.print("["+current.element+ "]" + " ");
current = current.next;
}
System.out.println();
}
}
public Node find(int index) {
Node current = first;
for(int i = 0; i < index; i++) {
current = current.next;
}
return current;
}
public void change(int index, int k) {
int count = 0;
while(count < k) {
Objects.checkIndex(index, size);
Node our = find(index);
temp = our.next;
our.next = our;
our = temp;
our = null;
count++;
index++;
}
}
}
Maybee, someone know how to do this.
When you swap two elements in a linked list, you actually need to modify up to three elements. For example, look at the following sub-list:
... -> a -> b -> c -> d -> ...
If you swap c and b, you get:
... -> a -> c -> b -> d -> ...
Now, the following has changed:
The next of a is now c (it was b).
The next of b is now d (it was c).
The next of c is now b (it was d).
Three nodes changed. Your code in the change() method only modifies two nodes, it forgets about node a.
Update
Possible implementation of a swap method:
/**
* Swaps the elements at the i-th and the (i-1)-th indices.
*/
public void swap(int index) {
Objects.checkIndex(index, size - 1);
if (index == 0) {
// Before swap: first -> x -> y
Node oldFirst = first;
Node x = first.next;
Node y = x.next;
// After swap: x -> first -> y
x.next = first;
first.next = y;
first = x;
// Update `last` if last two elements swapped
if (size == 2) {
last = oldFirst;
}
} else {
// Before swap: a -> b -> c -> d
Node a = find(index - 1);
Node b = a.next;
Node c = b.next;
Node d = c.next;
// After swap: a -> c -> b -> d
a.next = c;
b.next = d;
c.next = b;
// Update `last` if last two elements swapped
if (index == size - 2) {
last = b;
}
}
}

LinkedList (built from scratch) add() not working

I'm working on a class assignment where I must build a singly linkedlist class from scratch. My problem here is that my add() method isn't quite working when I iterate through a series of items and add them to a linkedlist. More specifically, 1) it is duplicating the first one in a series, and 2) it is not adding the last one in a series. What is wrong with my add() method in the ManualLinkedList class?
public class test {
static class ManualLinkedList<T> {
private static class Node<T> {
T item;
Node<T> next;
Node<T> prev;
public T getItem() {
return item;
}
public ManualLinkedList.Node<T> getNext() {
return next;
}
Node(Node<T> prev, T element, Node<T> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
Node<T> head;
Node<T> tail;
int size = 0;
public void add(T t) {
final Node<T> l = tail;
final Node<T> newNode = new Node<>(l, t, null);
tail = newNode;
if (l == null) {
head = newNode;
}
else {
l.next = newNode;
}
size++;
}
public int size() { return size; }
public T getContentFromPosition(int position) {
Node<T> np = head;
T result = head.getItem();
if (position == size) {
result = tail.getItem();
}
for (int i = 1; i < size; i++) {
if (i == position) {
result = np.getItem();
}
np = np.getNext();
}
return result;
}
} //end ManualLinkedList class
public static void main(String[] args) {
ManualLinkedList<Integer> test = new ManualLinkedList<>();
test.add(1);
test.add(2);
test.add(3);
test.add(4);
test.add(5);
test.add(6);
test.add(7);
test.add(8);
for (int i =0; i < test.size; i++){
System.out.println(test.getContentFromPosition(i));
}
}
}
Expected Output:
1
2
3
4
5
6
7
8
Actual Output:
1
1 // notice the duplicate first item
2
3
4
5
6
7 // notice the missing 8, or the last input
Primary Issues
index is used as 0..size-1 during invocation
for loop in getContentFromPosition should be from 0..size-1
The usage of size == position is irrelevant in getContentFromPosition
Code
public T getContentFromPosition(int position) {
if (position >= size) {
return null;
}
Node<T> np = head;
T result = head.getItem();
if (position == size - 1) {
result = tail.getItem();
}
for (int i = 0; i < size; i++) {
if (i == position) {
result = np.getItem();
break;
}
np = np.next;
}
return result;
}
} //end ManualLinkedList class
public static void main(String[] args) {
ManualLinkedList<Integer> test = new ManualLinkedList<>();
test.add(1);
test.add(2);
test.add(3);
test.add(4);
test.add(5);
test.add(6);
test.add(7);
test.add(8);
for (int i = 0; i < test.size; i++){
System.out.println(test.getContentFromPosition(i));
}
}
Your add function is actually fine.
However, your getContentFromPosition function is almost right, but needs a little work. You should decide whether the positions in your list count from 0 or from 1. For example, if there are 3 elements in a list, are they are positions 0, 1, 2 or positions 1, 2, 3?
When you are using the getContentFromPosition function from main, you are assuming that positions count from 0, but in writing the function, it looks like you were assuming that they count from 1.
If you modify the getContentFromPosition to count from 0, then you can get rid of the special case checking for position==size, and you would then start the loop at 0, not 1. Also, for efficiency, why not return the result when you find it rather than let the loop continue to run?
you need to initialized int size=1 instead of 0
and in the main method for loop change to int i=1 instead of 0
in getContentFromPosition method, your for loop should start from 0. Rest is fine.
for (int i = 0; i < size; i++)

Sierpinski carpet use a stack instead of recursion

I have implemented a solution to solve the Sierpinski carpet problem using recursion. Now I want to use a stack instead of the recursive method to solve the Sierpinski carpet. I am trying to translate my recursive method into the stack, but I am having trouble when I push the variables from my recursive method. This is the piece of code that I have to push and pop
drawGasket(x + i * sub, y + j * sub, sub);
When you call drawGasket(0, 0, 729), you should see the following on your screen:
Recursive method:
public void drawGasket(int x, int y, int side) {
int sub = side / 3;
//Draw center square
g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));
if(sub >= 3) {
//Draw 8 surrounding squares
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
if (j!=1 || i != 1)
drawGasket(x + i * sub, y + j * sub, sub);
}
}
}
}
Stack implementation:
public void stack (int x, int y, int side ){
GenericStack<Integer> s = new GenericStack<>();
int sub = side /3;
g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));
while (!s.isEmpty()){
x=s.pop();
if (sub >=3){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
if (j!=1 || i != 1){
int operation = x+i*sub;
s.push(operation);
int operation2 = y+j*sub;
s.push(operation2);
s.push(sub);
}
}
}
}
}
}
My Stack Class:
public class GenericStack<T> {
private int size; // size
private Node<T> head; // node head
public GenericStack() { // constructor
head = null; // head is null
size = 0; // size is zero
}
public void push(T element) {
if(head == null) { // if head is null
head = new Node(element); // head is node
} else {
Node<T> newNode = new Node(element);
newNode.next = head;
head = newNode;
}
size++;
}
public T pop() {
if(head == null)
return null;
else {
T topData = head.data;
head = head.next;
size--;
return topData;
}
}
public T top() {
if(head != null)
return head.data;
else
return null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
}
If you can picture the recursive version as already being stack-based, you should be able to translate your code appropriately. If you think of every recursive call to drawGasket(x + i * sub, y + j * sub, sub); as pushing three values onto a stack, and every first step "inside" the drawGasket method as popping three values off that stack, then explicitly pushing and popping those same values on and off your GenericStack in an iterative solution should follow the same pattern. Basically, just as in the recursive solution, you need to push, push, push successive values onto the stack until you run out of values to push; and then you need to pop, pop, pop successive values off the stack and "draw" a rectangle appropriate to the values just popped until the stack is empty.

Swapping nodes in a singly linked list java

I have been trying to come up with an algorithm to swap 2 nodes (not necesarily right next to each other) in a singly linked list for 2 days but for some reason I cannot do it.
Here is what I have, I am really new to coding and have been really stressed:
I have managed to place a temp node in but can't actually swap the nodes.
public void swap(int i, int j) {
current = head;
current2 = head;
sllNode temp = new sllNode(" ");
sllNode temp2 = new sllNode(" ");
for(int z = 0; i>z; z++)
current=current.next;
for(int q = 0; j>q; q++)
current2 = current2.next;
temp.next = current2.next.next;
current.next = temp;
current.next = current2.next.next;
current2.next = current;
Why exchange nodes, when you can exchange the data?
public void swap(int i, int j) {
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithNode = ithNode.next;
}
sllNode jthNode = head;
for (int q = 0; q < j; q++) {
jthNode = jthNode.next;
}
// Swap the data
String data = ithNode.data;
ithNode.data = jthNode.data;
jthNode.data = data;
}
It would make sense to use a method:
public sllNode get(int i) {
sllNode current = head;
while (i > 0) {
current = current.next;
}
return current;
}
By the way:
The convention for class names is a beginning capital: SllNode.
Do not use fields for things like current and current2 where they can be local variables.
Exchanging nodes, the hard way
Here one has to think, so it is best to deal with special cases first, and then only treat i < j.
public void swap(int i, int j) {
if (i >= size() || j >= size()) {
throw new IndexOutOfBoundsException();
}
if (i == j) {
return;
}
if (j < i) {
swap(j, i);
return;
}
// i < j
sllNode ithPredecessor = null;
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithPredecessor = ithNode;
ithNode = ithNode.next;
}
sllNode jthPredecessor = ithNode;
sllNode jthNode = ithNode.next;
for (int q = i + 1; q < j; q++) {
jthPredecessor = jthNode;
jthNode = jthNode.next;
}
// Relink both nodes in the list:
// - The jthNode:
if (ithPredecessor == null) {
head = jthNode;
} else {
ithPredecessor.next = jthNode;
}
sllNode jNext = jthNode.next;
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
jthNode.next = ithNode;
} else {
jthNode.next = ithNode.next;
}
// - The ithNode:
if (jthPredecessor == ithNode) {
} else {
jthPredecessor.next = ithNode;
}
ithNode.next = jNext;
}
No guarantee that the logic is okay. There are tricks:
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
Both conditions test whether i + 1 == j, but testing on a .next and then assigning makes the condition a momentary state. As you see it would have been easier to have one single if (i + 1 == j) { ... } else { ... } and handle both the ithNode and jthNode.
To do this, you need to swap 2 things: the node as next from the previous node, and the next node.
Once you found current and current2 which are the previous nodes of the nodes you want to swap, do this:
Swap the nodes:
sllNode tmp = current.next;
current.next = current2.next;
current2.next = tmp;
Then swap the next:
tmp = current.next.next;
current.next.next = current2.next.next;
current2.next.next = tmp;
// Swapping two elements in a Linked List using Java
import java.util.*;
class SwappingTwoElements {
public static void main(String[] args)
{
LinkedList<Integer> ll = new LinkedList<>();
// Adding elements to Linked List
ll.add(10);
ll.add(11);
ll.add(12);
ll.add(13);
ll.add(14);
ll.add(15);
// Elements to swap
int element1 = 11;
int element2 = 14;
System.out.println("Linked List Before Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
// Swapping the elements
swap(ll, element1, element2);
System.out.println();
System.out.println();
System.out.println("Linked List After Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
}
// Swap Function
public static void swap(LinkedList<Integer> list,
int ele1, int ele2)
{
// Getting the positions of the elements
int index1 = list.indexOf(ele1);
int index2 = list.indexOf(ele2);
// Returning if the element is not present in the
// LinkedList
if (index1 == -1 || index2 == -1) {
return;
}
// Swapping the elements
list.set(index1, ele2);
list.set(index2, ele1);
}
}
Output
Before Swapping Linked List :-
10 11 12 13 14 15
After Swapping Linked List :-
10 14 12 13 11 15
Time Complexity: O(N), where N is the Linked List length

Recursive function in java - N nested loops with changing indicies

Similar to this: Is there any way to do n-level nested loops in Java?
I want to create a recursive function, which generates N nested loops, where the indicies depend on the depth of the loop. So basically, I want to do this recursively:
// N = 3, so we want three nested loops
for(int i1 = 0; i1 < max; i1++){
for(int i2 = i1+1; i2 < max; i2++){
for(int i3 = i2+1; i3 < max; i3++){
int value1 = getValue(i1);
int value2 = getValue(i2);
int value3 = getValue(i3);
doSomethingWithTheValues( ... );
}
}
}
I've looked at the answers in the other question, and tried to modify the answer (by oel.neely), but without luck. My guess is that it only needs a small modification, but right now, I'm just confusing myself!
Its C#, but should be easily convertable to Java:
class ImmutableStack<T>
{
public readonly T Head;
public readonly ImmutableStack<T> Tail;
public ImmutableStack(T head, ImmutableStack<T> tail)
{
this.Head = head;
this.Tail = tail;
}
public static ImmutableStack<T> Cons(T head, ImmutableStack<T> tail)
{
return new ImmutableStack<T>(head, tail);
}
public static ImmutableStack<T> Reverse(ImmutableStack<T> s)
{
ImmutableStack<T> res = null;
while (s != null)
{
res = Cons(s.Head, res);
s = s.Tail;
}
return res;
}
}
class Program
{
static void AwesomeRecursion(int toDepth, int start, int max, ImmutableStack<int> indices)
{
if (toDepth < 0)
{
throw new ArgumentException("toDepth should be >= 0");
}
else if (toDepth == 0)
{
Console.Write("indices: ");
indices = ImmutableStack<int>.Reverse(indices);
while (indices != null)
{
Console.Write("{0}, ", indices.Head);
indices = indices.Tail;
}
Console.WriteLine();
}
else
{
for (int i = start; i < max; i++)
{
AwesomeRecursion(toDepth - 1, i + 1, max, ImmutableStack<int>.Cons(i, indices));
}
}
}
static void Main(string[] args)
{
AwesomeRecursion(4, 1, 10, null);
Console.WriteLine("Done");
Console.ReadKey(true);
}
}
We keep the indices on an immutable stack since it makes backtracking so much easier than mutable stacks or queues.

Categories

Resources