Array
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
char a[5] = {'h', 'e', 'l', 'l', 'o',}; |
a[0] = 'b'; |
result:
bello |
Dynamic Allocation of Arrays
A size-n
array can be created in this way:
char a[n]; |
But when writing the code, n
must be known.
If n
is unknown, how dose the program run?
char* a = NULL; |
Now a
is an empty array whose size is 5
.
// store somrthing in the array |
When done, free memory. Otherwise, memory leak can happen.
delete [] a; |
Removing an element in the middle has O(n)
time complexity. Require moving the remaining items leftward.
Vector
Vector is almost the same as array.
The main difference is that vector’s capacity can automatically grow.
New elements can be appended using push_back()
in O(1)
time(on average).
The last element can be removed using pop_back()
in O(1)
time.
std::vector<char> v = {'h', 'e', 'l', 'l', 'o'}; |
Vector can delete an element in the middle using erase()
in O(n)
time. So it is not better to do this.
std::vector<char> v(100); |
When size is going to exceed capacity, program will create a new array of capacity 200, copy the 100 elements from the old array to the new, put the new element in the 101st position and free the old array from memory.
List
A Node
A node contains a data and two pointers that one points to the previous node and another points to the next node.
Doubly Linked List
std::list<char> l = {'h', 'e', 'l', 'l', 'o'}; |
cout << l[2]; // does not work |
list<char>::iterator iter = l.begin(); |
Diference
Array | Vector | List | |
---|---|---|---|
Size | fixed | can increase and decrease | can increase and decrease |
Memory | contiguous | contiguous | not contiguous |
Array | Vector | List | |
---|---|---|---|
Rand Access | O(1) |
O(1) |
— |
push_back() |
— | O(1) (average) |
O(1) |
pop_back() |
— | O(1) |
O(1) |
insert() |
— | O(n) (average) |
O(1) |
erase() |
— | O(n) (average) |
O(1) |
Which shall we use?
Array: Fixed size throughout.
Vector:
- Random access(i.e., read or write the
i
-th element) is fast. - Insertion and deletion at the end are fas.
- insertion and deletion in the front and midddle are slow.
List:
- Sequentially visiting elements is fast; random access is not allowed.
- Frequent insertion and deletion at any position are OK.
Binary Search
int arr[] = {3, 5, 12, 16, 17, 26, 32, 51, 53, 64}; |
Inputs: (i) an array whose elements are in the accending order and (ii) a key.
Goal: Search for the key in the array. If found, return its index; if not found, return -1
.
Examle 1:
- Search for the elemnt
53
. - Return
8
.
Example 2:
- Search for the element 9.
- Return
-1
.
Example: key = 26
. Use two variables left
and right
pointing to the front of the array and the back respectively.
int search(int arr[], int left, int right, int key) |
How to suport both search and insertion?
std::vector<int> v = {3, 5, 12, 16, 17, 26, 32, 51, 53, 64}; |
The ascending order must be kept; otherwisem search would take O(n) time.
Inserting an item into the middle has O(n) time complexity(on average).
Can we perform binary search in the list?
No, Given left
and right
, we cannot get mid
efficiently.
Search | Insertion | |
---|---|---|
Vector | O(log n) | O(n) |
List | O(n) | O(1) |
Skip List | O(log n) | O(log n) |
- 本文标题:Data Structure
- 创建时间:2023-05-25 17:34:01
- 本文链接:2023/05/25/note/Algorithm/DataStrucuture/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!