Is there a similar function/operation in C that can do this for arrays in O(1) time? For example, [1, 2, 3, 4, 5] shifted by one space gives [2, 3, 4, 5, 0].
No. But you can produce the same result by just storing an offset and using modulo accesses
struct array {
int offset;
int size;
int elems[];
};
struct array* alloc_array(int size)
{
struct array *a = malloc(sizeof(struct array) + sizeof(int)*size);
a->offset = 0;
a->size = size;
return a;
}
/* Constant-time shift!
Just use shiftleft with a negative distance to shift right */
void shiftleft(struct array *a, int distance)
{
a->offset += distance;
}
/* Note we actually made each of our N element accesses slightly more expensive.
However, that was already linear (ie, when you print all elements)
so we still have the desired asymptotic complexity.
*/
int elem(struct array *a, int idx)
{
return a->elems[(idx + a->offset) % a->size];
}
NB. This is totally un-tested, it's just a sketch so you get the idea. Also, I've assumed you actually want an element shift, since that's what you showed. If you want to shift an array N bits to the left, it's a little more involved.
I found out that bit shifting uses a special circuit
PS. This "special circuit" is one of the CPU's built-in operations which operates in constant time on a fixed-size register. The register size is baked into the CPU hardware. The size of a C int
is chosen to match the CPU register size.
There is no way of performing a constant-time (per register) operation on N register-sized integers (for example) that doesn't take N times as long, so obviously it has linear complexity.
I know what I'm trying to achieve cannot be done in literal O(1) time.
Well, asymptotic complexity is only relevant if the number of elements varies. If you always operate on arrays of fixed size, even an operation that's linear with the number of elements is constant-time per array.
Edit - please stop saying that
bit-shifting in integers are considered O(1) time since they are so fast, even though they actually aren't O(1)
I said it was constant time because it is, assuming a modern ALU with a barrel shifter
if it wasn't constant-time, there is no value of "so fast" that would induce me to call it constant-time unless it always took the same number of clock cycles in practice (including reciprocal throughput). Since there's no practical way to measure when within a single clock cycle it completed, this is a distinction with no practical difference.
Again, speed and asymptotic complexity are orthogonal. There is no sufficiently small coefficient for an O(N) operation to be considered O(1). There is of course a sufficiently small value of N, which I mentioned below (but you have declined to bound N in your question).
If you always operate on arrays of variable but bounded size, you can sort of make the same claim, although if your effective array size covers multiple orders of magnitude it won't be very persuasive.
I would be satisfied by any answers that suggest how I could improve the speed of shifting the array so that it somewhat seems like an O(1) operation (even though it actually isn't).
That makes literally no sense. Asymptotic complexity is not a measure of speed, and optimizing speed has no effect on asymptotic complexity.