Best Way to create Adjacency List in java? - java

In general, to create Adjacency list of n node in java, we need to create an extra loop to fill the list with empty list like below-
for(int i=0;i<n;i++)
adj.add(new ArrayList<>());
Now we had to had to add the elements,but because of this extra loop its wasting the time.
Is there any other best way to create the adjacency list??????

If I need to make a compact representation of a graph, and I can get the neighbors for each vertex in sequence, I often do it like this:
//Concatenated adjacency lists for each vertex in order
ArrayList<Integer> adjList = new ArrayList<>();
//For each vertex, the end of its adjacency list in adjList
ArrayList<Integer> adjListEnds = new ArrayList<>();
for (int i=0; i<num_vertexes; ++i) {
for (int adj : getNeighbors(i)) {
adjList.add(adj);
}
adjListEnds.add(adjList.size());
}
Now, to get the neighbors of any vertex:
int s = vertex>0 ? adjListEnds.get(vertex-1) : 0;
int e = adjListEnds.get(vertex);
for (int i = s; i<e; ++i) {
processNeighbor(vertext, adjList.get(i));
}
Of course, if you want it to be really compact, then you should use something like an array list that holds primitive ints instead of Integers. Sometimes I roll my own. Sometimes I use gnu trove.

Related

How could i make a data structure like linked list, but each node holds N elements?

So I want to make a linked list type of structure in the sense that each "group" of N elements also holds either a NULL pointer or a pointer to the next group.
So for example, I read an integer of 4, i want then to create a structure which hold 4 integers plus a NULL pointer, and then later if I wish to create another group of 4 integers i can change the NULL pointer of the first group to point to the second group.
PS: i'd like to achieve this in Java
If I understood your question correctly, you want to add a group of N elements to a data structure, and then this group can reference another group of M elements, and so on.
You can use LinkedList of LinkedList.
LinkedList<LinkedList<Integer>> outerList = new LinkedList<>();
int input = 4;
LinkedList<Integer> innerList = new LinkedList<>();
for (int i = 0; i < input; i++) innerList.add(i);
outerList.add(innerList);
input = 3;
innerList = new LinkedList<>();
for (int i = 0; i < input; i++) innerList.add(i);
outerList.add(innerList);
LinkedList<Integer> myList = outerList.get(/*the index of the group you want*/);
myList.get(/*the element you want from that group*/);
Linked list is a data-structure that consists of nodes. Each node has a data and a next. The next is another node (or null if you are at the end of the list). Since data can be anything, you can define a List of the type of your choice. Example:
List<int[]> myList = new ArrayList<int[]>();
and then you can define each element as an array of n elements. You can use other data types as well.

how to add a matrix to an ArrayList in java

I need to add a number of matrces to an arraylist or some sort of collection in order to recall them at a later stage
I have tried the arraylist and arraycopy
List<Double> al = new ArrayList<>();
double [][] k = new double [d.length][d[0].length];
System.arraycopy (d,0,k,0,d.length);
for (int i1 =0; i1 < d.length; i1++)
k[i1] = k.add(D[i1]);
al.add(k[i1]);
for (Integer x : k)
System.out.print(x + " ");
print2D(k);
I need an array of say 4x4 matrices
If I do say al.add(d); I get error: cannot find suitable method to add double
even when al.add(Matrix)
You forgot the array as type for your generics. What you want is List<double[][]> and not List<Double>. Then you will be able to add your matrices to the list.
The addition is simple, just
list.add(matrix);
// or in your case:
al.add(k);
no need to copy anything around or access the individual entries in the matrices.
You can retrieve matrices via get for example:
double[][] firstMatrix = list.get(0);
The list must be a list of matrices, and you are declaring a list of Doubles. Try something like this:
List<double[][]> list = new ArrayList<>();
double[][] matrix = {{1D,1D},{2D,2D}};
list.add(matrix);
Hope that helps!

How to sort a List of ArrayLists (not arrays)?

I have an adjacency list implemented using a List[] of ArrayLists. I want to sort the List in descending order of the size of the ArrayLists. I figured I would do this by writing a Comparator... But how would I do this? or is this just not possible and I should do it another way?
Collections.sort(adjacency, new Comparator<ArrayList<Integer>()>() {
public int compare(ArrayList<Integer> p1, ArrayList<Integer> p2) {
return Integer.compare(p1.length, p2.length);
}
});
The code on top is not functioning. I tried with just an ArrayList, List[], List as a Comparator type. Is there a wrapper class for list? Sorry if this may sound uneducated.
This is how I made the adjacency list:
List<Integer>[] adjacency;
adjacency = (List<Integer>[]) new List[size];
for (int i = 0; i < size; ++i) {
adjacency[i] = new ArrayList<Integer>();
}
Thank you.
The code on top is not functioning.
The code is not working because p1 and p2 are ArrayLists and they dont have a field named length, they have the method size(), that is what you need.
return Integer.compare(p1.size(), p2.size());

How to create a class to handle multidimensional arraylist

During my search for info about multidimensional arraylist, I read that you could create a class to handle the multidimensional arraylist.
I'm doing a Android game similar to Bejeweled, and instead of using a common multidimensional grid, I guess this would be better!? I also has a list of all the sprite objects and I wonder if I can store and control all this objects with a multidimensional arraylist class?
But I'm not sure how a class would look like and how do I set and get values from the arraylists? Is there anyone who are interested to explain how it's working and show a simple code example? Thanks!
EDIT: I want to have objects in the arraylists like this example int grid[][] = new int[8][8]; but instead of integers, I want to have objects. And I wonder if it's possible to get and set values the same easy was like in the example I just showed?
EDIT 2: I have a grid 8x8 and that's why I'm using a array like [8][8], but I can only have values of type integers or booleans at each positions. I also have to use an arraylist to handle all the 64 objects that has a positions within this grid. Each object store it's position, both in the grid array and the position on the screen. I just wanted to make it a little bit simplier to handle and create a gird with multidimensional arrayList to both store the objects and have a grid? Possible or is there a better way to do this?
int size =8;
List<List<Integer>> list = new ArrayList<List<Integer>>(size);
for(int i=0; i<size; i++)
{
list.add(new ArrayList<Integer>());
}
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
Integer x = list.get(0).get(1); //access the 0,1 element
}
}
EDIT :
If you want to use a specific class. For ex: Node, you could use List<List<Node>> instead of List<List<Integer>> and then access it. You can then call any methods of the Node class as follows:
Node node = list.get(0).get(1); // access the Node at 0,1
node.getProperties();
There is no big difference between ArrayList and array.
Would say there are only 2 pros of ArrayList:
ability to dynamically change a size
adding new element at end of array, without need to look for first empty slot
And for multidimensional another pros is possibility to have different lengths for nested ArrayLists.
In Your case I think You don't need any of this so choose one You feel more comfortable, If You don't know how to make ArrayList of ArrayLists but know how to use array use them.
But just to answer Your question.
ArrayList<ArrayList<Object>> root = new ArrayList<ArrayList<Object>>();
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.get(1).set(1, Object); //puts new object at position 1,1
Object o = root.get(1).get(1); //gets object from position 1,1
With multidimensional array:
Object[][] grid = new Object[8][8];
grid[1][4] = new Object(); //set new object at position 1,4
grid[1][4].doSmth(); //calls method doSmth() of object stored at position 1,4
Object o = grid[1][4]; //gets object at position 1,4
List<List<Integer>> multiList = new ArrayList<List<Integer>>();
multiList.add(new ArrayList<Integer>());
Integer element = multi.get(0).get(0); // element at 0,0
First your start with defining your multi-dimensional arrayList
int size = 8;
List<List<YourClass>> 2dList = new ArrayList<List<YourClass>>(size);
then you initialize it
for(int rowIndex = 0; rowIndex < size; rowIndex++) {
List<YourClass> row = new ArrayList<YourClass>(size)
for(int columnIndex = 0; columnIndex < size; columnIndex++) {
row.add(new YourClass());
}
2dList.add(row);
}
now you have an sizexsize ArrayList with instances of your class
to access it:
2dList.get(rowIndex).get(columnIndex) // will return the YourClass-Object you placed there
if you want to replace the object on a certain position with another instance you need to remove the old object first:
2dList.get(rowIndex).remove(columnIndex);
2dList.get(rowIndex).add(columnIndex, newYourClass);

How to filter an array in Java?

How can I filter an array in Java?
I have an array of objects, for example cars:
Class:
public class Car{
public int doors;
public Car(int d){
this.doors = d;
}
}
Use:
Car [] cars = new Cars[4];
cars[0] = new Car(3);
cars[1] = new Car(2);
cars[2] = new Car(4);
cars[3] = new Car(6);
Now I want to filter the array of cars, keeping only 4 doors and more:
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
}
}
How should I do this?
Before I did it with a Vector:
Vector subset = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
subset.addElement(cars[i]);
}
}
And then I would make a new array with the size of the Vector. Then I would loop over the vector again and fill the new array. I know this is a very large procedure for something simple.
I'm using J2ME.
EDIT: saw that ArrayList is not in J2ME, but based on documentation, it does have a Vector. If that Vector class is different than J2SE Vector (as this documentation indicates), then perhaps the following code would work:
Vector carList = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
carList.addElement(cars[i]);
}
}
Car[] carArray = new Car[carList.size()];
carList.copyInto(carArray);
The most efficient way to do this--if the predicate you're filtering on is inexpensive and you're accessing it with a single thread--is usually to traverse the list twice:
public Car[] getFourDoors(Car[] all_cars) {
int n = 0;
for (Car c : all_cars) if (c.doorCount()==4) n++;
Car[] cars_4d = new Car[n];
n = 0;
for (Car c : all_cars) if (c.doorCount()==4) cars_4d[n++] = c;
return cars_4d;
}
This traverses the list twice and calls the test twice, but has no extra allocations or copying. The Vector-style methods traverse the list once, but allocates about twice the memory it needs (transiently) and copies every good element about twice. So if you are filtering a tiny fraction of the list (or performance isn't an issue, which very often it isn't), then the Vector method is good. Otherwise, the version above performs better.
If you really need a plain array as the result, I think your way is the way to go: you don't know the number of resulting elements before you filter, and you can't construct a new array without knowing the number of elements.
However, if you don't need thread-safety, consider using ArrayList instead of a Vector. It ought to be somewhat faster. Then use ArrayList's toArray method to get the array.
I can't see much wrong with your code. You could just stick with Vectors throughout though.
You could simplify the second part (where you copy the matching items into the new array) using Vector.copyInto(Object[]).
There's no direct way to remove elements from an array; its size is fixed. Whatever you do, you need to allocate a new array somehow.
If you want to avoid the minor memory overhead of allocating a Vector, another option would be to make two passes over your array. The first time, simply count the number of elements that you want to keep. Then allocate an array that size, and loop over your old array again, copying matching elements into the new array.
You can use System.arrayCopy():
Car[] cars = ...
int length = cars.length < 4 ? cars.length() : 4;
Car filter = new Car[4];
System.arrayCopy(cars, 0, filter, 0, length);
UPDATE: System.arrayCopy is available in Java ME API, unlike Vector.subList(). Thanks for the correction.
You will need to create a new array anyway.
Vector vector = new Vector(array.length);
for (int i = 0; i < array.length; i++) {
if (array[i].doors > 4) {
vector.add(array[i]);
}
}
Car[] result = new Car[vector.size()];
vector.copyInto(result);
This isn't quite efficient, though.

Categories