Avionics
Core avionics package for CURE flight computers
Loading...
Searching...
No Matches
CircularArray.h
Go to the documentation of this file.
1#ifndef CIRCULARARRAY_H
2#define CIRCULARARRAY_H
3
4#include <algorithm>
5#include <cstdint>
6#include <vector>
7
8template<typename T>
9int partition(std::vector<T>& array, int left, int right, int pivotIndex) {
10 T pivotValue = array[pivotIndex];
11 std::swap(array[pivotIndex], array[right]); // Move pivot to end
12 int storeIndex = left;
13 for (int i = left; i < right; i++) {
14 if (array[i] < pivotValue) {
15 std::swap(array[i], array[storeIndex]);
16 storeIndex++;
17 }
18 }
19 std::swap(array[storeIndex], array[right]); // Move pivot to its final place
20 return storeIndex;
21}
22
23// Quick select implementation
24// Returns the kth smallest element in the array
25// left and right are the bounds of the array
26// O(n) average time complexity
27// O(n^2) worst case time complexity
28// If we were to just use bubble sort, that would be O(n^2) time complexity
29template<typename T>
30T quickSelect(std::vector<T> &array, int left, int right, int k){
31 while (left < right){
32 int pivotIndex = (left + right) / 2;
33 int pivotNewIndex = partition(array, left, right, pivotIndex);
34 if (pivotNewIndex == k){
35 return array[k];
36 } else if (k < pivotNewIndex){
37 right = pivotNewIndex - 1;
38 } else {
39 left = pivotNewIndex + 1;
40 }
41 }
42 return array[k];
43}
44
45
46template<typename T>
53 protected:
54 std::vector<T> array;
55 uint8_t head; // 0 to 255
56 uint8_t maxSize; // 0 to 255
57 uint16_t pushCount; // 0 to 65535
58
59 public:
61 this->maxSize = maxSize;
62 this->head = 0;
63 this->pushCount = 0;
64 this->array = std::vector<T>(maxSize, T());
65 }
66
68 array.clear();
69 }
70
71 void push(T data){
72 // After the first push, start moving the head
73 if (pushCount)
74 head = (head + 1) % maxSize;
75 array[head] = data;
76 pushCount++;
77 }
78
79 T pop(){
80 if (pushCount == 0){
81 return T();
82 }
83 T data = array[head];
84 head = (head + maxSize - 1) % maxSize;
85 pushCount--;
86 return data;
87 }
88
89 // How many indexes back from the head
90 T getFromHead(uint8_t index){
91 return array[(head + maxSize - index) % maxSize];
92 }
93
94 // Has the circular array been filled
95 bool isFull(){
96 return pushCount >= maxSize;
97 }
98
99 bool isEmpty(){
100 return pushCount == 0;
101 }
102
103 uint8_t getHead(){
104 return head;
105 }
106
107 uint8_t getMaxSize(){
108 return maxSize;
109 }
110
112 if (pushCount == 0) {
113 // Handle the case when the array is empty
114 return T();
115 }
116
117 size_t count = std::min(static_cast<size_t>(pushCount), static_cast<size_t>(maxSize));
118 std::vector<T> copyArray(count);
119
120 // Collect the valid elements from the circular array
121 // TODO: Optimize (or just copy everything and restrict this function to only running when the array is full)
122 for (size_t i = 0; i < count; ++i) {
123 copyArray[i] = array[(head + maxSize - i) % maxSize];
124 }
125
126 // Find the median
127 return quickSelect(copyArray, 0, count - 1, count / 2);
128 }
129
130 void clear(){
131 head = 0;
132 pushCount = 0;
133 for (int i = 0; i < maxSize; i++){
134 array[i] = T();
135 }
136 }
137
138};
139
140
141
142#endif
T quickSelect(std::vector< T > &array, int left, int right, int k)
int partition(std::vector< T > &array, int left, int right, int pivotIndex)
void push(T data)
CircularArray(uint8_t maxSize)
uint8_t getHead()
uint16_t pushCount
T getFromHead(uint8_t index)
uint8_t getMaxSize()
std::vector< T > array