Beispiel #1
0
        private IEnumerator IEnumRandomQuickSort(T[] sort_item, QuickSortParameter <T> sort_parameter, int left, int right)
        {
            int[] pivot_index = new int[1];
            {
                int rand_index = Mathf.FloorToInt(UnityEngine.Random.Range(left, right - float.Epsilon));
                if (left != rand_index)
                {
                    swap_temp         = sort_item[left]; sort_item[left] = sort_item[rand_index]; sort_item[rand_index] = swap_temp;
                    dirty_items[left] = dirty_items[rand_index] |= SortItemState.Exchanged | SortItemState.Comparison;
                    sort_parameter.cb_action(SortState.Exchange, sort_item, dirty_items);
                    dirty_items[left] = dirty_items[rand_index] &= ~(SortItemState.Exchanged | SortItemState.Comparison);
                }
                else
                {
                    dirty_items[rand_index] |= SortItemState.Comparison;
                    sort_parameter.cb_action(SortState.Compare, sort_item, dirty_items);
                    dirty_items[rand_index] &= ~SortItemState.Comparison;
                }
            }
            //先頭に対して、大小を分ける。.
            dirty_items[left] |= SortItemState.Pivot;
            yield return(IEnumQuickSortBase(sort_item, sort_parameter, left + 1, right, left, pivot_index));

            dirty_items[left] &= ~SortItemState.Pivot;

            int back_ite = pivot_index[0] - 1;

            if (pivot_index[0] <= left)
            {
            }
            else
            {
                {//先頭と境界を入れ替える
                    swap_temp         = sort_item[left]; sort_item[left] = sort_item[pivot_index[0]]; sort_item[pivot_index[0]] = swap_temp;
                    dirty_items[left] = dirty_items[pivot_index[0]] |= SortItemState.Exchanged | SortItemState.Comparison;
                    sort_parameter.cb_action(SortState.Exchange, sort_item, dirty_items);
                    dirty_items[left] = dirty_items[pivot_index[0]] &= ~(SortItemState.Exchanged | SortItemState.Comparison);
                    yield return(waiter);
                }
            }
            dirty_items[pivot_index[0]] = SortItemState.SortEnd;
            if (pivot_index[0] > left)
            {
                for (int k = right - 1; k > pivot_index[0]; --k)
                {
                    dirty_items[k] |= SortItemState.DisableArea;
                }
                yield return(IEnumRandomQuickSort(sort_item, sort_parameter, left, pivot_index[0]));

                for (int k = right - 1; k > pivot_index[0]; --k)
                {
                    dirty_items[k] &= ~SortItemState.DisableArea;
                }
            }
            //この時点で左は完成してる
            if (pivot_index[0] + 1 < right)
            {
                yield return(IEnumRandomQuickSort(sort_item, sort_parameter, pivot_index[0] + 1, right));
            }
        }
Beispiel #2
0
        /// <summary>
        /// クイックソートのベース関数
        /// </summary>
        /// <param name="sort_item">[in,out]ソートアイテム</param>
        /// <param name="comparer">[in]比較演算</param>
        /// <param name="left">[in]ソートする左端(含む)</param>
        /// <param name="right">[in]ソートする右端(含まず)</param>
        /// <param name="pivot">[in]比較対象値</param>
        /// <param name="next_pivot_index">[out]比較対象との境界位置(左側列の再右端要素)</param>
        /// <returns></returns>
        private IEnumerator IEnumQuickSortBase(T[] sort_item, QuickSortParameter <T> sort_parameter, int left, int right, int pivot, int[] next_pivot_index)
        {
            int back_ite  = right;
            int dst_pivot = back_ite;
            int front_ite = left - 1;

            while (true)
            {//両端から、入れ替えの必要な二つを探して交換する
                if (front_ite >= left)
                {
                    dirty_items[front_ite] |= SortItemState.Comparison;
                }
                while (true)
                {
                    if (front_ite + 1 < back_ite)
                    {
                        --back_ite;
                        dirty_items[back_ite] |= SortItemState.Comparison;
                        sort_parameter.cb_action(SortState.Compare, sort_item, dirty_items);
                        dirty_items[back_ite] &= ~SortItemState.Comparison;
                        if (sort_parameter.comparer.Compare(sort_item[pivot], sort_item[back_ite]) > 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        next_pivot_index[0] = back_ite - 1;
                        if (front_ite >= left)
                        {
                            dirty_items[front_ite] &= ~SortItemState.Comparison;
                        }
                        yield break;
                    }
                }
                if (front_ite >= left)
                {
                    dirty_items[front_ite] &= ~SortItemState.Comparison;
                }
                dirty_items[back_ite] |= SortItemState.Comparison;
                while (true)
                {
                    if (front_ite + 1 < back_ite)
                    {
                        ++front_ite;
                        dirty_items[front_ite] |= SortItemState.Comparison;
                        sort_parameter.cb_action(SortState.Compare, sort_item, dirty_items);
                        dirty_items[front_ite] &= ~SortItemState.Comparison;
                        if (sort_parameter.comparer.Compare(sort_item[pivot], sort_item[front_ite]) < 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        next_pivot_index[0]    = back_ite;
                        dirty_items[back_ite] &= ~SortItemState.Comparison;
                        yield break;
                    }
                }
                dirty_items[back_ite] &= ~SortItemState.Comparison;
                swap_temp              = sort_item[front_ite]; sort_item[front_ite] = sort_item[back_ite]; sort_item[back_ite] = swap_temp;
                dirty_items[front_ite] = dirty_items[back_ite] |= SortItemState.Exchanged | SortItemState.Comparison;
                sort_parameter.cb_action(SortState.Exchange, sort_item, dirty_items);
                dirty_items[front_ite] = dirty_items[back_ite] &= ~(SortItemState.Exchanged | SortItemState.Comparison);
                yield return(waiter);
            }
        }