I have a large NumPy array `nodes = np.arange(100_000_000)` and I need to rearrange this array by:

1. Recording and then removing the middle value in the array
2. Split the array into the `left` half and `right` half
3. Repeat Steps 1-2 for each half
4. Stop when all values are exhausted

So, for a smaller input example `nodes = np.arange(10)`, the output would be:

```
[5 2 8 1 4 7 9 0 3 6]

```

This was accomplished by naively doing:

```
import numpy as np

def split(node, out):
    mid = len(node) // 2
    out.append(node[mid])
    return node[:mid], node[mid+1:]

def reorder(a):
    nodes = [a.tolist()]
    out = []

    while nodes:
        tmp = []
        for node in nodes:
            for n in split(node, out):
                if n:
                    tmp.append(n)
        nodes = tmp

    return np.array(out)

if __name__ == "__main__":
    nodes = np.arange(10)
    print(reorder(nodes))

```

However, this is way too slow for `nodes = np.arange(100_000_000)` and so I am looking for a much faster solution.