Visualization of one of the simplest data structure in Computer Science: **Array** (and its sorted form) surprisingly has not been done in VisuAlgo since its inception 2011-January 2024...

Stay tuned while we improve this page and its features.

**Remarks**: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.

If you are an NUS student and a repeat visitor, please __login__.

(Compact) Array is among the easiest and the most versatile data structure in Computer Science. Array is built-in almost all programming languages, e.g., C++, Python ('array' is called as 'list' in Python), Java, etc.

We can use (Compact) Array to implement List ADT.

We can use (Compact) Array to solve many classic problems. When not being used as a List ADT implementation (where positional order matters), it is often beneficial to first __sort__ the elements first so that we can utilize faster algorithms.

Pro-tip 1: Since you are not __logged-in__, you may be a first time visitor (or not an NUS student) who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode: **[PageDown]**/**[PageUp]** to go to the next/previous slide, respectively, (and if the drop-down box is highlighted, you can also use **[→ or ↓/← or ↑]** to do the same),and **[Esc]** to toggle between this e-Lecture mode and exploration mode.

Please see __List ADT__ overview.

Pro-tip 2: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution **or larger** (typical modern laptop resolution in 2021). We recommend using Google Chrome to access VisuAlgo. Go to full screen mode (**F11**) to enjoy this setup. However, you can use zoom-in (**Ctrl +**) or zoom-out (**Ctrl -**) to calibrate this.

(Compact) Array is a good candidate for implementing the List ADT as it is a simple construct to handle a collection of items.

When we say compact array, we mean an array that has **no gap**, i.e., if there are **N** items in the array (that has size **M**, where **M ≥ N**), then only index [0..**N**-1] are occupied and other indices [**N**..**M**-1] should remain **empty**.

Pro-tip 3: Other than using the typical media UI at the bottom of the page, you can also control the animation playback using keyboard shortcuts (in Exploration Mode): **Spacebar** to play/pause/replay the animation, **←**/**→** to step the animation backwards/forwards, respectively, and **-**/**+** to decrease/increase the animation speed, respectively.

Let the **compact** array name be `A` with index [0..**N**-1] occupied with the items of the list.

`get(i)`, just return `A[i]`.

This simple operation will be unnecessarily complicated if the array is **not** compact.

`search(v)`, we check each index `i` ∈ [0..**N**-1] one by one to see if `A[i] == v`.

This is because `v` (if it exists) can be anywhere in index [0..**N**-1].

Since this visualization only accept distinct items, `v` can only be found at most once.

In a general List ADT, we may want to have `search(v)` returns a list of indices.

`insert(i, v)`, we shift items ∈ [**i**..**N**-1] to [**i**+1..**N**] (*from backwards*) and set `A[i] = v`.

This is so that `v` is inserted correctly at index `i` and maintain compactness.

`remove(i)`, we shift items ∈ [**i+1**..**N**-1] to [**i**..**N**-2], overwriting the old `A[i]`.

This is to maintain compactness.

`get(i)` is very fast: Just one access, O(**1**).

Another CS course: 'Computer Organisation' discusses the details on this O(**1**)

performance of this array indexing operation.

`search(v)`

In the best case, **v** is found at the first position, O(**1**).

In the worst case, **v** is not found in the list and we require O(**N**) scan to determine that.

`insert(i, v)`

In the best case, insert at **i = N**, there is no shifting of element, O(**1**).

In the worst case, insert at **i = 0**, we shift all **N** elements, O(**N**).

`remove(i)`

In the best case, remove at **i = N-1**, there is no shifting of element, O(**1**).

In the worst case, remove at **i = 0**, we shift all **N** elements, O(**N**).

The size of the compact array **M** is not infinite, but a finite number. This poses a problem as the maximum size may not be known in advance in many applications.

If **M** is too big, then the unused spaces are wasted.

If **M** is too small, then we will run out of space easily.

Solution: Make **M** a variable. So when the array is full, we create a larger array (usually two times larger) and move the elements from the old array to the new array. Thus, there is no more limits on size other than the (usually large) physical computer memory size.

__C++ STL std::vector__, __Python list__, __Java Vector__, or __Java ArrayList__ all implement this variable-size array. Note that Python *list* and Java Array*List* are **not** Linked Lists, but are actually variable-size arrays. This array visualization implements this doubling-when-full strategy.

However, the classic array-based issues of space wastage and copying/shifting items overhead are still problematic.

There are various applications that can be done on a Compact (Integer) Array **A**:

- Searching for a specific value
**v**in array**A**, - Finding the min/max or the k-th smallest/largest value in (static) array
**A**, - Testing for uniqueness and deleting duplicates in array
**A**, - Counting how many time a specific value
**v**appear in array**A**, - Set intersection/union between array
**A**and another sorted array**B**, - Finding a target pair
**x**∈**A**and**y**∈**A**such that**x+y**equals to a target**z**, - Counting how many values in array
**A**is inside range [**lo**..**hi**], etc.

See __unsorted array__ and __sorted array__ hints.

We will outline the possible actions that you can do in this page. For now, just try to guess based on the name of the function.

We will talk about the two modes: array (the content can be unsorted) versus sorted array (the content must always be sorted, without loss of generality: sorted in non-decreasing order).

There are already lots of (simple) applications that we can do with unsorted array.

- We can use O(
**N**) linear search (leftmost to rightmost or vice versa) to find**v**, - For min/max, we can use O(
**N**) linear search again;

for k-th smallest/largest, we may need to use O(**kN**) algorithm^{1}, - We can use O(
**N^2**) nested-loop to see if any two indices in**A**are the same, - We may need to use
__Hash Table__to do this in O(**N**), - O(
**N^2**) nested-loop is needed, - O(
**N^2**) nested-loop is needed, - We may need to use
__Hash Table__to do this in O(**N**).

There are better ways, especially if the array if sorted.

^{1}There is a faster expected O(**N**) QuickSelect or O(**N**) worst-case linear time selection.

When the array is sorted, we open up a lot of possibilities.

- We can use O(log
**N**) binary search on a sorted array, - A[0]/A[k-1]/A[N-k]/A[N-1] are the min/k-th smallest/k-th largest/max value in (static sorted) array
**A**, - Duplicates, if any, will be next to each other in a sorted array
**A**, - Same as above,
- We can use modifications of merge routine of Merge Sort,
- We can use two pointers method,
- The index of
**y**- the index of**x**+ 1 (use two binary searches).

There can be other ways.

You have reached the last slide. Return to 'Exploration Mode' to start exploring!

Note that if you notice any bug in this visualization or if you want to request for a new visualization feature, do not hesitate to drop an email to the project leader: Dr Steven Halim via his email address: stevenhalim at gmail dot com.

__Close__

Create(M, N)

Insert(v)

Remove(i)

Select

Update

Special