Skip to content

Instantly share code, notes, and snippets.

@a3geek
Last active July 5, 2018 11:08
Show Gist options
  • Save a3geek/e78c52789f22c78cfdb1978ffadbdeaa to your computer and use it in GitHub Desktop.
Save a3geek/e78c52789f22c78cfdb1978ffadbdeaa to your computer and use it in GitHub Desktop.
Bitonic Sort for Unity C#
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
namespace Gists
{
public static class BitonicSort
{
public const float InvertLogTwo = 1f / 0.6931471805f; // 1.0 / loge2
public static void Sort<T>(ref T[] array, T valueForShortage = default(T)) where T : IComparable
{
var length = array.Length;
if(length <= 0)
{
return;
}
CheckArrayLength(ref array, valueForShortage);
var log = Mathf.Log(length) * InvertLogTwo; // this.length = 2 ^ log
for(var width = 0; width < log; width++)
{
for(var height = 0; height <= width; height++)
{
var step = 1 << (width - height); // 2 ^ (width - height)
for(var i = 0; i < length; i++)
{
var skip = i & step; // d間隔で0とdを繰り返す
// i >> width = width * 2間隔で0,1,2,3とインクリメントさせていく
var up = ((i >> width) & 2) == 0; // width * 2 * 2間隔で0と2を繰り返す
if(skip == 0 && (array[i].CompareTo(array[i + step]) > 0) == up)
{
var tmp = array[i];
array[i] = array[i + step];
array[i + step] = tmp;
}
}
}
}
}
public static void CheckArrayLength<T>(ref T[] array, T valueForShortage)
{
var length = array.Length;
if(length <= 0 || Mathf.IsPowerOfTwo(length) == true)
{
return;
}
var shortage = Mathf.NextPowerOfTwo(length) - length;
var arr = new T[length + shortage];
Array.Copy(array, arr, length);
for(var i = length; i < arr.Length; i++)
{
arr[i] = valueForShortage;
}
array = arr;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment