Data Structures, Algorithms, & Applications in Java
Chapter 8, Exercise 25

The code is given below.
public class TridiagonalAsIrregularArray
{
   // data members
   int rows;              // matrix dimension
   Object zero;           // zero element
   Object [][] element;   // element array

   // constructor
   public TridiagonalAsIrregularArray(int theRows, Object theZero)
   {
      // validate theRows
      if (theRows < 1)
         throw new IllegalArgumentException
                   ("number of rows must be > 0");
   
      rows = theRows;
      zero = theZero;

      // create and initialize the irregular array
      element = new Object [rows][];
      // do row 1 of the matrix
      element[0] = new Object [2];
      element[0][0] = element[0][1] = zero;
      // do row rows of the matrix
      element[rows - 1] = new Object [2];
      element[rows - 1][0] = element[rows - 1][1] = zero;
      // do the remaining ros
      for (int i = 1; i < rows - 1; i++)
      {
         element[i] = new Object[3];
         element[i][0] = element[i][1] = element[i][2] = zero;
      }

   }
   
   // methods
   /** throws IndexOutOfBoundsException when i < 1
     * or j < 1 or i > rows or j > rows */
   void checkIndex(int i, int j)
   {
      if (i < 1 || j < 1 || i > rows || j > rows)
         throw new IndexOutOfBoundsException
                   ("i = " + i + " j = " + j +
                    " rows = " + rows + " cols = " + rows);
   }

   /** return the element this(i,j)
     * throws IndexOutOfBoundsException when i or j invalid */
   public Object get(int i, int j)
   {
      checkIndex(i, j);

      // determine element to return
      if (i - j >= -1 && i - j <= 1)
      {// in the tridiagonal
         if (i == 1)
            return element[i - 1][j - 1];
         else
            return element[i - 1][j - i + 1];
       }
       else
         // not in the tridiagonal
         return zero;
   }
   
   /** set this(i,j) = newValue
     * throws IndexOutOfBoundsException when i or j invalid */
   public void set(int i, int j, Object newValue)
   {
      checkIndex(i, j);

      // store newValue
      if (i - j >= -1 && i - j <= 1)
      {// in the tridiagonal
         if (i == 1)
            element[i - 1][j - 1] = newValue;
         else
            element[i - 1][j - i + 1] = newValue;
      }
      else
         // not in the tridiagonal
         if (!((Zero) newValue).equalsZero())
                   throw new IllegalArgumentException
                         ("elements not on tridiagonal must be zero");
   }
}



(a)
The test program and output appear in the files TridiagonalAsIrregularArray.*.

(b)
The irregular array representation needs space for the rows entries of element[] in addition to space for the 3*rows-2 entries of the tridiagonal. Therefore, approximately 33% extra space is required. The differential is higher if we represent a boolean matrix rather than a generic matrix. In this case, 4rows bytes are needed for the references in the boolean array element[][] and (3rows - 2)/8 bytes are needed for the boolean entries of the tridiagonal. When using the one-dimensional array representation, the 3rows - 2 entries of the boolean array element require only (3rows - 2)/8 bytes of space. So the irregular array representation takes almost 12 times as much space as does the one-dimensional array representation.

When representing a matrix of type double or long, rather than a generic matrix, the relative space overhead incurred by the irregular array scheme is less because each matrix element takes 8 bytes, whereas each reference of element[] still takes 4 bytes.

With respect to run time, methods such as input, output, add, etc. can be implemented using a single for loop when the one-dimensional array representation is used (see Exercise 15). When the irregular array representation is used, two nested for loops are needed. Because of the added overheads of having two loops rather than one and of having to index into a two-dimensional array rather than into a one-dimensional array, we expect the one-dimensional array representation to be faster than the irregular array representation.