How can I visualize what the loop is doing when traversing through a 2d array

Consider this code:

    import java.util.Arrays;
public class test {
    
    
    static int[] getDiagonal(int[][] a) {
        int diagonal[] = new int[a.length];
        for(int i = 0; i<a.length; i++) {
                diagonal[i] = a[i][i];
            
        }
        Out.println(Arrays.toString(diagonal));
        return diagonal;
        
    }
    
    public static void main(String[] args) {
        int[][] rnd_array = {{1,2,4},{6,7,3},{11,4,5}};
        
        getDiagonal(rnd_array);
    }
}

The goal of this code is to get the diagonal of a 2d matrix that has the same number of rows and coloumns.The code works just fine but I dont understand how.The part that isnt clear to me is how are we able to traverse both rows and coloums of a 2d array with just one loop.I’ve tried doing it with 2 for loops but I am not getting the wanted results.How could I visualize the traversal of a 2d array,and how is it possible that we are able to traverse it with only 1 loop?

Thank you!

Answer

Java doesn’t have 2D arrays. The only thing it does have is some very light syntax sugar support for making 1D arrays whose components are themselves 1D arrays. This can look like a 2D array for all intents and purposes, but it also highlights the trick for how to ‘visualize’ working with what you termed ‘2D arrays’.

> int[][] a

This is no different from any other array declaration, and java does not have 2D arrays. Therefore, you should read that as X[] a, where X is any type. After all, you can make int[], but you can also make String[] or List<?>[] – you can make an array out of any type. In this case, you’re making an array whose components are of the int[] type: An array of int arrays.

Crucial thing to understand: Those component arrays do NOT need to be the same size! This is perfectly legit java code:

int[][] a = new int[][2];
// just like any other array of non-primitives,
// each component slot starts out as null!

System.out.println(a[0]);
> null
// see?

a[0] = new int[5];
System.out.println(Arrays.asList(a[0]));
> [0, 0, 0, 0, 0]
a[0][2] = 9;
System.out.println(Arrays.asList(a[0]));
> [0, 0, 9, 0, 0]

a[0] is an expression that resolves to whatever is in the first ‘slot’ of the array referenced by your a variable. The [2] that follows immediately after is then applying the ‘and give me the 3rd slot’ to whatever you found at a[0]. So, a[0][2] is: The third slot in the array you find by looking in the first slot of the thing a is pointing at.

a[1] = new int[3]

Now you don’t have a 2D array in any sense of the word. Because the first ‘row’ of your ‘2D’ array has 5 elements and the second row has only 3.

a = new int[10][10];

This is that light syntax sugar I told you about earlier: This is just syntax sugar for:

a = new int[][10];
for (int i = 0; i < a.length; i++) {
    a[i] = new int[10];
}

The part that isnt clear to me is how are we able to traverse both rows and coloums of a 2d array with just one loop

That’s good news! Because your code does not traverse both rows and columns of a 2D array at all. What it is doing is hitting the diagonal and only the diagonal.

First, realize that this code fundamentally assumes you don’t have a ‘broken’ array like we made before – that it is an array of arrays of size X, and each array component is also of size X. Otherwise it’s going to throw exceptions.

With that established, let’s visualize that array-of-arrays:

0 1 2
3 4 5
6 7 8

Then this code is just hitting a[0][0], a[1][1], and a[2][2]: Just 0, 4, and 8. That’s only 3 elements. Makes sense; the diagonal of a 15×15 array consists of 15 numbers – that math almost works out. So, there is no need to loop over 9 elements in this example 3×3 array to ‘find’ the numbers on the diagonal.

If you really wanted to run this code but with a full loop (which is entirely inefficient), but just for sake of learning:

for (int x = 0; i < a.length; x++) {
    for (int y = 0; j < a[x].length; y++) {
        if (x == y) {
           // it is on the diagonal!
           diagonal[x] = a[x][y];
        } else {
           // not on the diagonal, so...
           // do not do anything at all.
        }
    }
}

That works fine too. It’s just a slower, as it needs to check out n^2 elements instead of just looking at a[i][i] which only needs to check n elements.

Leave a Reply

Your email address will not be published. Required fields are marked *