前者は push / pop が常に O(1) だけど書き出し時(連続領域の配列としてアクセスしたいとき)に(たぶん)常に O(N) かかります。
後者は push/pop が O(1) にならない(償却できるかは知らん)代わりに、常に O(1) で連続領域の配列に乗ったデータにアクセスできます
リングバッファ自体は、内部データがバッファ両端を跨いでいても動く(→push / pop が O(1) になる)のがメリットなので、そのメリットを潰さず連続領域にデータを乗せたいなら、
・外部のバッファに書き出す関数を用意する
・少ないずらし頻度で連続領域に乗せる
のどちらかになるかと。
この図は後者の実装です
リングバッファ、これでいいのかな?><;(ちゃんとテストしてない><;)
https://gist.github.com/orange-in-space/ccdbd35835fc51b7c9d9ba6bce6ee9f9
Circular Buffer in .NET
https://social.msdn.microsoft.com/Forums/vstudio/en-US/416a2175-b05d-43b1-b99a-a01c56550dbe/circular-buffer-in-net?forum=netfxbcl
10年前のコレが上位に出てくるあたり、今も標準にはなさそう……(知らんが)