Arrays and Special Matrices
Arrays are the most fundamental storage structure in programming, and almost every other data structure is built on top of them. For special matrices and sparse matrices that contain many repeated elements or many zero elements, compressed storage saves a great deal of space, which is why it is a frequent topic in the postgraduate entrance exam. This chapter revolves around one core question, namely how to store a matrix in less space, and develops the address computation of multidimensional arrays, the compressed storage schemes for special matrices, and the two classic representations of sparse matrices. After reading this chapter you will be able to master the storage structure of one-dimensional and two-dimensional arrays, compute the address of any element, understand the address formulas for row-major and column-major storage together with the difference between them, apply the compressed storage formulas for symmetric, lower-triangular and tridiagonal matrices, master the triple representation and the orthogonal list representation of sparse matrices, and use compressed storage to solve problems of matrix access and matrix operations.
A 10×10 matrix needs 100 storage units, yet a symmetric matrix really needs only half of them, and a sparse matrix may need only a few dozen non-zero elements. How can a matrix be compressed to the smallest possible space while still allowing any element to be accessed? Answering that question requires the row-major and column-major address formulas of multidimensional arrays, the compression patterns of symmetric, triangular and tridiagonal matrices, and the triple and orthogonal list representations of sparse matrices.
Basic route: storage of multidimensional arrays → compressed storage of special matrices; master the address computation formulas first.
Advanced route: sparse matrices → typical applications → summary; understand when the triple representation and the orthogonal list are the right choice.
Definition
A definition is a precise description of what a concept, a term, or an object means. Understanding definitions is the foundation of learning any field, and every concept has its own exact meaning.
An array is an ordered collection of data elements of the same type, laid out linearly in memory by index. A multidimensional array is expanded into a single linear storage layout in memory in either row-major or column-major order.
One-Dimensional Arrays
Let the base address of the one-dimensional array be and let every element occupy storage units. Then:
Two-Dimensional Arrays (Row-Major)
Let the two-dimensional array have rows and columns. In row-major storage the address of the element is:
Derivation: in row-major order there are elements before row , and there are further elements before column of row , so the offset is .
Two-Dimensional Arrays (Column-Major)
In column-major storage the address of the element is:
Derivation: there are elements before column , and there are further elements before row of column , so the offset is .
Exercises
Exercise 1
A two-dimensional array A[0..4][0..5] is stored in row-major order. If every element occupies 2 storage units and the address of A[0][0] is 1000, what is the address of A[3][4]? ( )
A. 1034 B. 1040 C. 1044 D. 1048
Approach:
This question tests the computation of an element address in a two-dimensional array stored in row-major order. First determine the number of rows and columns from the index ranges, then write down the row-major offset formula, and finally substitute the base address together with the element size to obtain the target address.
Steps:
- From the array has 5 rows and 6 columns, so the column count is .
- In row-major storage the offset of is ; substituting , and gives an offset of .
- Every element occupies 2 storage units, so the address is .
Answer:
C (1044).
Exercise 2
How are multidimensional arrays stored in memory, and how is the address of an element computed?
Approach:
This question tests the two linear storage layouts of a multidimensional array together with their address formulas. In the answer, first explain that a multidimensional array can only be flattened into a one-dimensional sequence in memory, then write the row-major and the column-major address formulas in turn, and explain the meaning of every symbol in the formulas.
Steps:
- Explain that a multidimensional array is stored linearly in memory in either row-major or column-major order.
- Write the row-major formula : there are elements before row , and further elements before column of row .
- Write the column-major formula : there are elements before column , and further elements before row of column .
- Explain that and are the number of rows and the number of columns, while is the length in storage units occupied by one element.
Answer:
A multidimensional array is expanded linearly in memory in either row-major or column-major order. In row-major order ; in column-major order . Here and are the row count and the column count, and is the size of one element.
A special matrix is a matrix that contains many identical elements or many zero elements. It can be stored in compressed form in a one-dimensional array, which saves space.
Symmetric Matrices
A symmetric matrix satisfies , so only the lower triangle including the diagonal has to be stored, which takes elements.
The index of the lower-triangular element (with ) in the one-dimensional array is:
Derivation: there are elements before row , and there are further elements before column of row .
Lower-Triangular Matrices
The storage scheme is the same as for a symmetric matrix, except that the upper triangle is represented by a single constant, so storage units are needed.
Tridiagonal Matrices (Banded Matrices)
A tridiagonal matrix has non-zero elements only on the main diagonal and the two diagonals next to it, that is, non-zero elements in total. Stored in row-major order, the index of (with ) is:
Derivation: there are elements before row (each of the first rows contributes 3 elements, except that the first row contributes only 2), and within row the element in column is the -th one.
Exercises
Exercise 1
Suppose a 10×10 symmetric matrix A is stored in compressed form, with its lower triangle kept in a one-dimensional array B. What is the index of A[5][3] (indices counted from 0) in B? ( )
A. 13 B. 14 C. 15 D. 16
Approach:
This question tests the computation of an element index for a symmetric matrix that is compressed into its lower triangle. First confirm that the element in question lies in the lower-triangular region, then apply the index formula of lower-triangular compressed storage, and finally substitute and to locate it in the one-dimensional array B.
Steps:
- A symmetric matrix satisfies , and compressed storage keeps only the lower triangle including the diagonal, so can be located directly inside the lower triangle.
- The index of the lower-triangular element (with ) is , where is the total number of elements in all rows before row , and is the number of elements before column within row .
- Substituting and gives , so the correct option is C.
Answer:
C (15).
Exercise 2
Briefly describe how the compressed storage formula for a symmetric matrix is derived.
Approach:
This question tests the derivation of the compressed storage formula for a symmetric matrix. In the answer, first use the symmetry to show that only the lower triangle has to be kept, then count the total number of elements in that triangle, and finally split the index into the elements of all preceding rows and the offset inside the current row to derive the formula.
Steps:
- By the symmetry only the lower triangle including the diagonal has to be stored, and this triangle contains elements.
- Split the index into two parts: the total number of elements in all rows before row is , and the number of elements before column within row is .
- Adding the two parts gives the index formula (valid for ).
Answer:
A symmetric matrix satisfies , so only the lower triangle including the diagonal has to be stored. That triangle contains elements. The index of the element (with ) is , where is the total number of elements in all rows before row , and is the number of elements before column within row .
A sparse matrix is a matrix in which the number of non-zero elements is far smaller than the number of zero elements, typically with fewer than 5 percent non-zero elements.
Triple Representation
Only the row number, the column number and the value of each non-zero element are stored, represented by a table of triples:
#define MAXSIZE 100
typedef struct {
int row; // row number
int col; // column number
int value; // element value
} Triple;
typedef struct {
Triple data[MAXSIZE];
int rows, cols, nums; // number of rows, columns and non-zero elements
} TSMatrix;
Advantages: it saves an enormous amount of storage space. Disadvantages: accessing an arbitrary element requires a traversal and a search, so the efficiency is low.
Orthogonal List Representation
The non-zero elements are stored as linked list nodes, and every non-zero element node is attached simultaneously to a row list and a column list, which makes matrix addition, multiplication and similar operations convenient.
typedef struct OLNode {
int row, col, value;
struct OLNode *right; // points to the next non-zero element in the same row
struct OLNode *down; // points to the next non-zero element in the same column
} OLNode, *OLink;
Exercises
Exercise 1
How is a sparse matrix stored in compressed form, and which methods are available?
Approach:
This question tests the compressed storage methods for a sparse matrix. In the answer, first state the core idea that a sparse matrix stores only its non-zero elements and their positions, then list the three mainstream representations one by one together with the situations in which each of them applies, and finally summarize the common advantages and disadvantages of such compressed storage.
Steps:
- Non-zero elements occupy only a very small proportion of a sparse matrix, so the core of compressed storage is to keep only the non-zero elements and their positions, which reduces the space cost from to a quantity proportional to the number of non-zero elements.
- Triple representation: an array of (row number, column number, value) records holds the non-zero elements; it saves space but slows down random access.
- Orthogonal list representation: every non-zero element node is attached to a row list and to a column list at the same time, which makes matrix operations convenient.
- Compressed row and column storage (CSR and CSC): three arrays store the values, the column numbers and the row offsets respectively, which suits large-scale sparse matrix computation.
- Overall comparison: the advantages are the saved storage space and the reduced number of useless operations; the disadvantages are the low efficiency of random access and the considerable complexity of the algorithms.
Answer:
A sparse matrix stores only its non-zero elements and their positions, and the three common methods are the triple representation, the orthogonal list representation and compressed row and column storage. The advantages are the saved storage space and the reduced number of useless operations; the disadvantages are the low efficiency of random access and the complexity of the algorithm implementation.
The compressed storage of arrays and matrices is not pure theory: from image processing to the solution of large-scale systems of equations, the storage layout of the data often decides how fast a program can run. This section puts the sequential storage, the address computation and the compressed storage formulas described above back into real scenarios, and explains when an ordinary two-dimensional array is good enough and when it is worth paying the extra cost of index conversion for a special matrix.
Typical Applications of Arrays
- Data storage: putting data of the same type into a contiguous block of memory and locating an element directly by base address plus index times element length is the basis of almost every program.
- Searching and sorting: binary search relies on the orderedness of an array and on its random access capability; classic sorting algorithms such as insertion sort, merge sort and quicksort are all built on top of arrays.
- Matrix operations: image processing, linear algebra and state space computation all perform matrix multiplication, and the contiguous storage of an array directly determines the memory access pattern and the cache hit rate.
Typical Applications of Sparse Matrices
- Adjacency matrices of graphs: when a sparse graph is stored as an adjacency matrix, almost every position is 0; switching to the triple representation or the orthogonal list keeps only the non-zero elements and reduces the storage from to a quantity proportional to the number of non-zero elements.
- Scientific computing: the matrices produced by the numerical solution of partial differential equations or by the finite element method are often non-zero only near the main diagonal, so compressed storage is the standard practice.
- Solving large-scale systems of equations: sparse matrix factorizations such as LU and Cholesky exploit the structure of the zero elements to skip useless computation, which is the key to solver performance.
Trade-offs in Choosing a Representation
| Scenario | Recommended approach | Reason |
|---|---|---|
| Dense elements with frequent access by index | An ordinary two-dimensional array | The address computation is simple and the access is |
| Special structure such as symmetric, triangular or tridiagonal | Storage by the compressed formula | The storage can be halved or reduced even further, at the cost of index conversion |
| Very few non-zero elements | Triples or an orthogonal list | The storage is proportional to the real information content, but random access becomes slower |
Common Misconceptions
What compressed storage saves is space, and what it costs is that locating an element by index is no longer a single multiplication and addition but may become a table lookup or even a full traversal. Compressed storage therefore only pays off when the structure of the matrix is genuinely special and the access pattern is dominated by whole-block traversal; if the code frequently accesses a compressed matrix at random by index, the trade-off is usually a bad one.
Returning to the formulas of this chapter: the index conversion of a symmetric matrix is (for ), the tridiagonal matrix uses , and a triple of a sparse matrix is the combination of three numbers, namely (row, column, value). Memorize these three expressions and combine them with the selection table above, and you will be able to decide which storage scheme a concrete question calls for.
The conclusion of this chapter can be compressed into one sentence: the price of an array is paid in random access by index, and the price of a matrix is paid in storing it more compactly according to its structure. The terminology table aligns terms such as row-major order, symmetric matrix, triple and orthogonal list with their English names, while the key takeaways gather the address formulas and the compressed index formulas that have to be remembered, so that one quick pass before the exam connects all the formulas of this chapter.
Terminology Reference
| Term | Abbreviation | Explanation |
|---|---|---|
| Row-major | - | Stored row by row |
| Column-major | - | Stored column by column |
| Symmetric matrix | - | Satisfies A[i][j] = A[j][i] |
| Compressed storage | - | Keeps only the meaningful elements |
| Sparse matrix | - | A matrix with very few non-zero elements |
| Triple | - | A non-zero element represented as (row, column, value) |
| Orthogonal list | - | Row and column doubly linked storage |
Key Takeaways
- Row-major address formula:
- Compressed index of a symmetric matrix: (for )
- Compressed index of a tridiagonal matrix:
- A sparse matrix is stored with triples or an orthogonal list, which saves space but slows down random access
