What's wrong with my recursion logic?
I'm trying to find the size of an m-ary tree. An MTree Node's children is represented by an ArrayList I implemented. My logic was to have a for loop as big as m so I could check every child.
public AnyType element;
public int m; // MTreeNode will have m children at most
public static ArrayList<MTreeNode> children;
public MTreeNode(AnyType element, int m, ArrayList<MTreeNode> children){
this.element = element;
this.m = m;
this.children = children;
public static int size(MTreeNode<?> t){
int nodes = 0;
if(t == null)
return 0;
else{
for(int i = 0; i < t.m; i++){
size(t.children.get(i));
}
return 1 + nodes;
}
}
I'm getting my error at
size(t.children.get(i));
Related
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.
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++)
I have a question according to A*-Algorithm, which I have implemented in Java.
So, I have a grid of nodes with randomly generated obstacles and a Player, who can walk over the grid.
But I got a Problem. If I click on an obstacle no path is generated, but this is exactly what I want to. So I want to generate the best path the Point I click on to especially to an obstacle.
My idea is to take a boolean flag, but I never get my Problem solved. Maybe some of u guys see the Problem.
Heres the A*-Method:
public List<Node> findPath(int startx,int starty,int endx,int endy){
for(int i = 0;i<cols;i++){
for(int j = 0;j<rows;j++){
grid[i][j] = new Node(i,j,obstacles[i][j]);
}
}
for(int i = 0;i<cols;i++){
for(int j = 0;j<rows;j++){
grid[i][j].addNeighbours(grid);
}
}
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Node start = grid[startx][starty];
Node end = grid[endx][endy];
openList.add(start);
while(openList.size() > 0){
int winner = 0;
for(int i = 0;i <openList.size();i++){
if(openList.get(i).f < openList.get(winner).f){
winner = i;
}
}
Node current = openList.get(winner);
openList.remove(current);
closedList.add(current);
if(nosolution==false){
if(current == end){
List<Node> path = new ArrayList<Node>();
Node tmp = current;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
openList.clear();
closedList.clear();
Collections.reverse(path);
return path;
}
}else{
nosolution=true;
}
List<Node> neighbours = current.neighbours;
for(int i = 0;i<neighbours.size();i++){
Node neighbour = neighbours.get(i);
if(!closedList.contains(neighbour) && !neighbour.obstacle){
int tempG = current.g + 1;
boolean newPath = false;
if(openList.contains(neighbour)){
if(tempG < neighbour.g){
neighbour.g = tempG;
newPath = true;
}
}
else{
neighbour.g = tempG;
newPath = true;
openList.add(neighbour);
}
if(newPath){
neighbour.h = heuristic(neighbour,end);
neighbour.f = neighbour.g + neighbour.h;
neighbour.previous = current;
}
}
}
}
return null;
}
Here the Node class:
public class Node{
public int x;
public int y;
public int g;
public int h;
public int f;
public List<Node> neighbours;
public Node previous;
public boolean obstacle;
public Node(int x,int y,boolean obstacle) {
this.x = x;
this.y = y;
this.g = 0;
this.h = 0;
this.f = 0;
this.previous = null;
this.obstacle = obstacle;
this.neighbours = new ArrayList<Node>();
}
public List<Node> addNeighbours(Node[][] grid){
int x = this.x;
int y = this.y;
if(x < 25 - 1){
neighbours.add(grid[x+1][y]);
}
if(x > 0){
neighbours.add(grid[x-1][y]);
}
if(y < 20 - 1){
neighbours.add(grid[x][y+1]);
}
if(y > 0){
neighbours.add(grid[x][y-1]);
}
return neighbours;
}
When no solution is found, and you still want to know the best solution that got closest to your destination, then look at the closedList and pick the Node with the smallest distance to the destination.
For a better answer, provide the code to Node as well if you need more help.
Update
Node has the x and y. Look through all the closed nodes, find the one closest to the target. Then construct a path using the previous field.
Since there might be many closed nodes, you may want to adjust the algorithm a bit to keep track of the closest node instead, and return that path when no solution exists.
public ArrayList findPath(int startx,int starty,int endx,int endy){
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Node start = grid[startx][starty];
Node end = grid[endx][endy];
Node closest = start;
openList.add(start);
while(!openList.isEmpty()){
int winner = 0;
for(int i = 0;i <openList.size();i++){
if(openList.get(i).f < openList.get(winner).f){
winner = i;
}
}
Node current = openList.get(winner);
openList.remove(current);
closedList.add(current);
if(current == end){
path = new ArrayList<Node>();
Node tmp = current;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
return path;
}
List<Node> neighbours = current.neighbours;
for(int i = 0;i<neighbours.size();i++){
Node neighbour = neighbours.get(i);
int cost = current.g + heuristic(current,neighbour);
if(openList.contains(neighbour) && cost < neighbour.g){
openList.remove(neighbour);
}
if(closedList.contains(neighbour) && cost < neighbour.g){
closedList.remove(neighbour);
}
if(openList.contains(neighbour) == false && closedList.contains(neighbour) == false && neighbour.obstacle == false){
neighbour.g = cost;
int newcost = heuristic(closest,end);
closest.h = newcost;
if(neighbour.h < closest.h){
closest = neighbour;
}
openList.add(neighbour);
neighbour.f = neighbour.g + neighbour.h;
neighbour.previous = current;
}
}
}
if(closest!=end){
path = new ArrayList<Node>();
Node tmp = closest;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
}
return path;
}
I'm trying to learn Prim's algorithm and I'm using this website to do so, but I'm having trouble making the code part of it run. I'm confused with what goes in public static int Prims(Vector<Vector<node>> adjList) and how to get the code to compile and run. (New to java so excuse me if its a silly question).
edit: This is the code I'm trying to run:
class node implements Comparable<node> {
int weight, index;
public node(int weight, int index) {
this.weight = weight;
this.index = index;
}
public int compareTo(node e) {
return weight - e.weight;
}
}public static int Prims(Vector<Vector<node>> adjList) {
// Current cost of MST.
int cost = 0;
int n = adjList.size();
PriorityQueue<node> pq = new PriorityQueue<node>();
// Keep track if each node is visited.
boolean visited[] = new boolean[n];
for (int i = 0; i < n; i++) {
visited[i] = false;
}
// Number of nodes visited.
int inTree = 1;
// Mark starting node as visited.
visited[0] = true;
// Add all edges of starting node.
for (int i = 0; i < adjList.get(0).size(); i++) {
pq.add(adjList.get(0).get(i));
}
// Keep going until all nodes visited.
while (!pq.isEmpty() && inTree < n) {
// Get the edge with the smallest weight.
node cur = pq.poll();
// Skip if node already used.
if (visited[cur.index]) {
continue;
}
inTree++;
visited[cur.index] = true;
cost += cur.weight;
// Add all the edges of the new node to the priority queue.
for (int i = 0; i < adjList.get(cur.index).size(); i++) {
pq.add(adjList.get(cur.index).get(i));
}
}
// Graph not connected if number of nodes used is less than total nodes.
if (inTree < n) {
return -1;
}
return cost;
}
Your method public static int Prims(Vector<Vector<node>> adjList) does not appear to be a member of a class. It needs to be. The leading } on the line
}public static int Prims(Vector<Vector<node>> adjList) {
should probable be moved to the end of the file.
If you do not use an IDE to compile and run a code you need to issue the following commands:
javac MyCode.java
java MyCode
where I suppose your code resides in a file named MyCode.java and there is no package defined.
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.