You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hello-algo/en/docs/chapter_array_and_linkedlist/array.md

799 lines
20 KiB

11 months ago
---
comments: true
---
8 months ago
# 4.1   Array
11 months ago
7 months ago
An <u>array</u> is a linear data structure that operates as a lineup of similar items, stored together in a computer's memory in contiguous spaces. It's like a sequence that maintains organized storage. Each item in this lineup has its unique 'spot' known as an <u>index</u>. Please refer to Figure 4-1 to observe how arrays work and grasp these key terms.
11 months ago
8 months ago
![Array definition and storage method](array.assets/array_definition.png){ class="animation-figure" }
11 months ago
8 months ago
<p align="center"> Figure 4-1 &nbsp; Array definition and storage method </p>
11 months ago
8 months ago
## 4.1.1 &nbsp; Common operations on arrays
11 months ago
8 months ago
### 1. &nbsp; Initializing arrays
11 months ago
10 months ago
Arrays can be initialized in two ways depending on the needs: either without initial values or with specified initial values. When initial values are not specified, most programming languages will set the array elements to $0$:
11 months ago
=== "Python"
```python title="array.py"
# Initialize array
arr: list[int] = [0] * 5 # [ 0, 0, 0, 0, 0 ]
nums: list[int] = [1, 3, 2, 5, 4]
```
=== "C++"
```cpp title="array.cpp"
/* Initialize array */
// Stored on stack
int arr[5];
int nums[5] = { 1, 3, 2, 5, 4 };
// Stored on heap (manual memory release needed)
int* arr1 = new int[5];
int* nums1 = new int[5] { 1, 3, 2, 5, 4 };
```
=== "Java"
```java title="array.java"
/* Initialize array */
int[] arr = new int[5]; // { 0, 0, 0, 0, 0 }
int[] nums = { 1, 3, 2, 5, 4 };
```
=== "C#"
```csharp title="array.cs"
/* Initialize array */
11 months ago
int[] arr = new int[5]; // [ 0, 0, 0, 0, 0 ]
11 months ago
int[] nums = [1, 3, 2, 5, 4];
```
=== "Go"
```go title="array.go"
/* Initialize array */
var arr [5]int
// In Go, specifying the length ([5]int) denotes an array, while not specifying it ([]int) denotes a slice.
// Since Go's arrays are designed to have compile-time fixed length, only constants can be used to specify the length.
// For convenience in implementing the extend() method, the Slice will be considered as an Array here.
nums := []int{1, 3, 2, 5, 4}
```
=== "Swift"
```swift title="array.swift"
/* Initialize array */
let arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]
let nums = [1, 3, 2, 5, 4]
```
=== "JS"
```javascript title="array.js"
/* Initialize array */
var arr = new Array(5).fill(0);
var nums = [1, 3, 2, 5, 4];
```
=== "TS"
```typescript title="array.ts"
/* Initialize array */
let arr: number[] = new Array(5).fill(0);
let nums: number[] = [1, 3, 2, 5, 4];
```
=== "Dart"
```dart title="array.dart"
/* Initialize array */
List<int> arr = List.filled(5, 0); // [0, 0, 0, 0, 0]
List<int> nums = [1, 3, 2, 5, 4];
```
=== "Rust"
```rust title="array.rs"
/* Initialize array */
let arr: Vec<i32> = vec![0; 5]; // [0, 0, 0, 0, 0]
let nums: Vec<i32> = vec![1, 3, 2, 5, 4];
```
=== "C"
```c title="array.c"
/* Initialize array */
int arr[5] = { 0 }; // { 0, 0, 0, 0, 0 }
int nums[5] = { 1, 3, 2, 5, 4 };
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
```
11 months ago
=== "Zig"
```zig title="array.zig"
// Initialize array
var arr = [_]i32{0} ** 5; // { 0, 0, 0, 0, 0 }
var nums = [_]i32{ 1, 3, 2, 5, 4 };
```
8 months ago
### 2. &nbsp; Accessing elements
11 months ago
10 months ago
Elements in an array are stored in contiguous memory spaces, making it simpler to compute each element's memory address. The formula shown in the Figure below aids in determining an element's memory address, utilizing the array's memory address (specifically, the first element's address) and the element's index. This computation streamlines direct access to the desired element.
11 months ago
8 months ago
![Memory address calculation for array elements](array.assets/array_memory_location_calculation.png){ class="animation-figure" }
11 months ago
8 months ago
<p align="center"> Figure 4-2 &nbsp; Memory address calculation for array elements </p>
11 months ago
10 months ago
As observed in the above illustration, array indexing conventionally begins at $0$. While this might appear counterintuitive, considering counting usually starts at $1$, within the address calculation formula, **an index is essentially an offset from the memory address**. For the first element's address, this offset is $0$, validating its index as $0$.
11 months ago
Accessing elements in an array is highly efficient, allowing us to randomly access any element in $O(1)$ time.
=== "Python"
```python title="array.py"
def random_access(nums: list[int]) -> int:
7 months ago
"""Random access to elements"""
# Randomly select a number from the interval [0, len(nums)-1]
11 months ago
random_index = random.randint(0, len(nums) - 1)
7 months ago
# Retrieve and return a random element
11 months ago
random_num = nums[random_index]
return random_num
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Random access to elements */
11 months ago
int randomAccess(int[] nums) {
7 months ago
// Randomly select a number in the interval [0, nums.length)
11 months ago
int randomIndex = ThreadLocalRandom.current().nextInt(0, nums.length);
7 months ago
// Retrieve and return a random element
11 months ago
int randomNum = nums[randomIndex];
return randomNum;
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{RandomAccess}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{random_access}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{randomAccess}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{random_access}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{randomAccess}
11 months ago
```
8 months ago
### 3. &nbsp; Inserting elements
11 months ago
10 months ago
Array elements are tightly packed in memory, with no space available to accommodate additional data between them. Illustrated in Figure below, inserting an element in the middle of an array requires shifting all subsequent elements back by one position to create room for the new element.
11 months ago
8 months ago
![Array element insertion example](array.assets/array_insert_element.png){ class="animation-figure" }
11 months ago
8 months ago
<p align="center"> Figure 4-3 &nbsp; Array element insertion example </p>
11 months ago
10 months ago
It's important to note that due to the fixed length of an array, inserting an element will unavoidably result in the loss of the last element in the array. Solutions to address this issue will be explored in the "List" chapter.
11 months ago
=== "Python"
```python title="array.py"
def insert(nums: list[int], num: int, index: int):
7 months ago
"""Insert element num at `index`"""
# Move all elements after `index` one position backward
11 months ago
for i in range(len(nums) - 1, index, -1):
nums[i] = nums[i - 1]
7 months ago
# Assign num to the element at index
11 months ago
nums[index] = num
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Insert element num at `index` */
11 months ago
void insert(int[] nums, int num, int index) {
7 months ago
// Move all elements after `index` one position backward
11 months ago
for (int i = nums.length - 1; i > index; i--) {
nums[i] = nums[i - 1];
}
7 months ago
// Assign num to the element at index
11 months ago
nums[index] = num;
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{Insert}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{insert}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{insert}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{insert}
11 months ago
```
8 months ago
### 4. &nbsp; Deleting elements
11 months ago
7 months ago
Similarly, as depicted in Figure 4-4, to delete an element at index $i$, all elements following index $i$ must be moved forward by one position.
11 months ago
8 months ago
![Array element deletion example](array.assets/array_remove_element.png){ class="animation-figure" }
11 months ago
8 months ago
<p align="center"> Figure 4-4 &nbsp; Array element deletion example </p>
11 months ago
10 months ago
Please note that after deletion, the former last element becomes "meaningless," hence requiring no specific modification.
11 months ago
=== "Python"
```python title="array.py"
def remove(nums: list[int], index: int):
7 months ago
"""Remove the element at `index`"""
# Move all elements after `index` one position forward
11 months ago
for i in range(index, len(nums) - 1):
nums[i] = nums[i + 1]
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Remove the element at `index` */
11 months ago
void remove(int[] nums, int index) {
7 months ago
// Move all elements after `index` one position forward
11 months ago
for (int i = index; i < nums.length - 1; i++) {
nums[i] = nums[i + 1];
}
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{Remove}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{removeItem}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{remove}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{remove}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{remove}
11 months ago
```
10 months ago
In summary, the insertion and deletion operations in arrays present the following disadvantages:
11 months ago
8 months ago
- **High time complexity**: Both insertion and deletion in an array have an average time complexity of $O(n)$, where $n$ is the length of the array.
- **Loss of elements**: Due to the fixed length of arrays, elements that exceed the array's capacity are lost during insertion.
- **Waste of memory**: Initializing a longer array and utilizing only the front part results in "meaningless" end elements during insertion, leading to some wasted memory space.
11 months ago
8 months ago
### 5. &nbsp; Traversing arrays
11 months ago
10 months ago
In most programming languages, we can traverse an array either by using indices or by directly iterating over each element:
11 months ago
=== "Python"
```python title="array.py"
def traverse(nums: list[int]):
7 months ago
"""Traverse array"""
11 months ago
count = 0
7 months ago
# Traverse array by index
11 months ago
for i in range(len(nums)):
count += nums[i]
7 months ago
# Traverse array elements
11 months ago
for num in nums:
count += num
7 months ago
# Traverse both data index and elements
11 months ago
for i, num in enumerate(nums):
count += nums[i]
count += num
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Traverse array */
11 months ago
void traverse(int[] nums) {
int count = 0;
7 months ago
// Traverse array by index
11 months ago
for (int i = 0; i < nums.length; i++) {
count += nums[i];
}
7 months ago
// Traverse array elements
11 months ago
for (int num : nums) {
count += num;
}
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{Traverse}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{traverse}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{traverse}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{traverse}
11 months ago
```
8 months ago
### 6. &nbsp; Finding elements
11 months ago
10 months ago
Locating a specific element within an array involves iterating through the array, checking each element to determine if it matches the desired value.
11 months ago
10 months ago
Because arrays are linear data structures, this operation is commonly referred to as "linear search."
11 months ago
=== "Python"
```python title="array.py"
def find(nums: list[int], target: int) -> int:
7 months ago
"""Search for a specified element in the array"""
11 months ago
for i in range(len(nums)):
if nums[i] == target:
return i
return -1
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Search for a specified element in the array */
11 months ago
int find(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target)
return i;
}
return -1;
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{Find}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{find}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{find}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{find}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{find}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{find}
11 months ago
```
8 months ago
### 7. &nbsp; Expanding arrays
11 months ago
10 months ago
In complex system environments, ensuring the availability of memory space after an array for safe capacity extension becomes challenging. Consequently, in most programming languages, **the length of an array is immutable**.
11 months ago
10 months ago
To expand an array, it's necessary to create a larger array and then copy the elements from the original array. This operation has a time complexity of $O(n)$ and can be time-consuming for large arrays. The code are as follows:
11 months ago
=== "Python"
```python title="array.py"
def extend(nums: list[int], enlarge: int) -> list[int]:
7 months ago
"""Extend array length"""
# Initialize an extended length array
11 months ago
res = [0] * (len(nums) + enlarge)
7 months ago
# Copy all elements from the original array to the new array
11 months ago
for i in range(len(nums)):
res[i] = nums[i]
7 months ago
# Return the new array after expansion
11 months ago
return res
```
=== "C++"
```cpp title="array.cpp"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "Java"
```java title="array.java"
7 months ago
/* Extend array length */
11 months ago
int[] extend(int[] nums, int enlarge) {
7 months ago
// Initialize an extended length array
11 months ago
int[] res = new int[nums.length + enlarge];
7 months ago
// Copy all elements from the original array to the new array
11 months ago
for (int i = 0; i < nums.length; i++) {
res[i] = nums[i];
}
7 months ago
// Return the new array after expansion
11 months ago
return res;
}
```
=== "C#"
```csharp title="array.cs"
7 months ago
[class]{array}-[func]{Extend}
11 months ago
```
=== "Go"
```go title="array.go"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "Swift"
```swift title="array.swift"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "JS"
```javascript title="array.js"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "TS"
```typescript title="array.ts"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "Dart"
```dart title="array.dart"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "Rust"
```rust title="array.rs"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
=== "C"
```c title="array.c"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
8 months ago
=== "Kotlin"
```kotlin title="array.kt"
7 months ago
[class]{}-[func]{extend}
8 months ago
```
8 months ago
=== "Ruby"
```ruby title="array.rb"
7 months ago
[class]{}-[func]{extend}
8 months ago
```
11 months ago
=== "Zig"
```zig title="array.zig"
7 months ago
[class]{}-[func]{extend}
11 months ago
```
8 months ago
## 4.1.2 &nbsp; Advantages and limitations of arrays
11 months ago
10 months ago
Arrays are stored in contiguous memory spaces and consist of elements of the same type. This approach provides substantial prior information that systems can leverage to optimize the efficiency of data structure operations.
11 months ago
8 months ago
- **High space efficiency**: Arrays allocate a contiguous block of memory for data, eliminating the need for additional structural overhead.
- **Support for random access**: Arrays allow $O(1)$ time access to any element.
- **Cache locality**: When accessing array elements, the computer not only loads them but also caches the surrounding data, utilizing high-speed cache to enchance subsequent operation speeds.
11 months ago
However, continuous space storage is a double-edged sword, with the following limitations:
8 months ago
- **Low efficiency in insertion and deletion**: As arrays accumulate many elements, inserting or deleting elements requires shifting a large number of elements.
- **Fixed length**: The length of an array is fixed after initialization. Expanding an array requires copying all data to a new array, incurring significant costs.
- **Space wastage**: If the allocated array size exceeds the what is necessary, the extra space is wasted.
11 months ago
8 months ago
## 4.1.3 &nbsp; Typical applications of arrays
11 months ago
10 months ago
Arrays are fundamental and widely used data structures. They find frequent application in various algorithms and serve in the implementation of complex data structures.
11 months ago
8 months ago
- **Random access**: Arrays are ideal for storing data when random sampling is required. By generating a random sequence based on indices, we can achieve random sampling efficiently.
- **Sorting and searching**: Arrays are the most commonly used data structure for sorting and searching algorithms. Techniques like quick sort, merge sort, binary search, etc., are primarily operate on arrays.
- **Lookup tables**: Arrays serve as efficient lookup tables for quick element or relationship retrieval. For instance, mapping characters to ASCII codes becomes seamless by using the ASCII code values as indices and storing corresponding elements in the array.
- **Machine learning**: Within the domain of neural networks, arrays play a pivotal role in executing crucial linear algebra operations involving vectors, matrices, and tensors. Arrays serve as the primary and most extensively used data structure in neural network programming.
- **Data structure implementation**: Arrays serve as the building blocks for implementing various data structures like stacks, queues, hash tables, heaps, graphs, etc. For instance, the adjacency matrix representation of a graph is essentially a two-dimensional array.