Copyright | (c) 2008-2011 Dan Doel (c) Dong Han 2017-2018 |
---|---|
License | BSD |
Maintainer | winterland1989@gmail.com |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
This module provide three stable sorting algorithms, which are:
mergeSort
, a O(log(n)) general-purpose sorting algorithms for all different size vectors.insertSort
a O(n^2) sorting algorithms suitable for very small vectors.radixSort
a O(n) sorting algorithms based onRadix
instance, which is prefered on large vectors.
Sorting is always performed in ascending order. To reverse the order, either use XXSortBy
or use Down
, RadixDown
newtypes. In general changing comparing functions can be done by creating auxiliary newtypes and Ord
instances (make sure you inline instance's method for performence!). Or Radix
instances in radixSort
case, for example:
data Foo = Foo { key :: Int16, ... } instance Radix Foo where -- You should add INLINE pragmas to following methods bucketSize = bucketSize . key passes = passes . key radixLSB = radixLSB . key radix i = radix i . key radixMSB = radixMSB . key
Synopsis
- mergeSort :: forall v a. (Vec v a, Ord a) => v a -> v a
- mergeSortBy :: forall v a. Vec v a => (a -> a -> Ordering) -> v a -> v a
- mergeTileSize :: Int
- insertSort :: (Vec v a, Ord a) => v a -> v a
- insertSortBy :: Vec v a => (a -> a -> Ordering) -> v a -> v a
- newtype Down a = Down {
- getDown :: a
- radixSort :: forall v a. (Vec v a, Radix a) => v a -> v a
- class Radix a where
- newtype RadixDown a = RadixDown a
- mergeDupAdjacent :: (Vec v a, Eq a) => v a -> v a
- mergeDupAdjacentLeft :: Vec v a => (a -> a -> Bool) -> v a -> v a
- mergeDupAdjacentRight :: Vec v a => (a -> a -> Bool) -> v a -> v a
- mergeDupAdjacentBy :: Vec v a => (a -> a -> Bool) -> (a -> a -> a) -> v a -> v a
Sort
mergeSort :: forall v a. (Vec v a, Ord a) => v a -> v a Source #
O(n*log(n)) Sort vector based on element's Ord
instance with classic
mergesort algorithm.
This is a stable sort, During sorting two O(n) worker arrays are needed, one of
them will be freezed into the result vector. The merge sort only begin at tile
size larger than mergeTileSize
, each tile will be sorted with insertSort
, then
iteratively merged into larger array, until all elements are sorted.
mergeSortBy :: forall v a. Vec v a => (a -> a -> Ordering) -> v a -> v a Source #
mergeTileSize :: Int Source #
The mergesort tile size, mergeTileSize = 8
.
insertSort :: (Vec v a, Ord a) => v a -> v a Source #
O(n^2) Sort vector based on element's Ord
instance with simple
insertion-sort algorithm.
This is a stable sort. O(n) extra space are needed, which will be freezed into result vector.
insertSortBy :: Vec v a => (a -> a -> Ordering) -> v a -> v a Source #
The Down
type allows you to reverse sort order conveniently. A value of type
contains a value of type Down
aa
(represented as
).
If Down
aa
has an
instance associated with it then comparing two
values thus wrapped will give you the opposite of their normal sort order.
This is particularly useful when sorting in generalised list comprehensions,
as in: Ord
then sortWith by
Down
x
Since: base-4.6.0.0
Instances
Monad Down | Since: base-4.11.0.0 |
Functor Down | Since: base-4.11.0.0 |
Applicative Down | Since: base-4.11.0.0 |
Foldable Down | Since: base-4.12.0.0 |
Defined in Data.Foldable fold :: Monoid m => Down m -> m # foldMap :: Monoid m => (a -> m) -> Down a -> m # foldMap' :: Monoid m => (a -> m) -> Down a -> m # foldr :: (a -> b -> b) -> b -> Down a -> b # foldr' :: (a -> b -> b) -> b -> Down a -> b # foldl :: (b -> a -> b) -> b -> Down a -> b # foldl' :: (b -> a -> b) -> b -> Down a -> b # foldr1 :: (a -> a -> a) -> Down a -> a # foldl1 :: (a -> a -> a) -> Down a -> a # elem :: Eq a => a -> Down a -> Bool # maximum :: Ord a => Down a -> a # | |
Traversable Down | Since: base-4.12.0.0 |
Eq1 Down | Since: base-4.12.0.0 |
Ord1 Down | Since: base-4.12.0.0 |
Defined in Data.Functor.Classes | |
Read1 Down | Since: base-4.12.0.0 |
Defined in Data.Functor.Classes | |
Show1 Down | Since: base-4.12.0.0 |
NFData1 Down | Since: deepseq-1.4.3.0 |
Defined in Control.DeepSeq | |
Bounded a => Bounded (Down a) | Since: base-4.14.0.0 |
Enum a => Enum (Down a) | Since: base-4.14.0.0 |
Defined in Data.Ord | |
Eq a => Eq (Down a) | Since: base-4.6.0.0 |
Floating a => Floating (Down a) | Since: base-4.14.0.0 |
Fractional a => Fractional (Down a) | Since: base-4.14.0.0 |
Integral a => Integral (Down a) | Since: base-4.14.0.0 |
Data a => Data (Down a) | Since: base-4.12.0.0 |
Defined in Data.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Down a -> c (Down a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Down a) # toConstr :: Down a -> Constr # dataTypeOf :: Down a -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Down a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Down a)) # gmapT :: (forall b. Data b => b -> b) -> Down a -> Down a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Down a -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Down a -> r # gmapQ :: (forall d. Data d => d -> u) -> Down a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Down a -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Down a -> m (Down a) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Down a -> m (Down a) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Down a -> m (Down a) # | |
Num a => Num (Down a) | Since: base-4.11.0.0 |
Ord a => Ord (Down a) | Since: base-4.6.0.0 |
Read a => Read (Down a) | This instance would be equivalent to the derived instances of the
Since: base-4.7.0.0 |
Real a => Real (Down a) | Since: base-4.14.0.0 |
Defined in Data.Ord toRational :: Down a -> Rational # | |
RealFloat a => RealFloat (Down a) | Since: base-4.14.0.0 |
Defined in Data.Ord floatRadix :: Down a -> Integer # floatDigits :: Down a -> Int # floatRange :: Down a -> (Int, Int) # decodeFloat :: Down a -> (Integer, Int) # encodeFloat :: Integer -> Int -> Down a # significand :: Down a -> Down a # scaleFloat :: Int -> Down a -> Down a # isInfinite :: Down a -> Bool # isDenormalized :: Down a -> Bool # isNegativeZero :: Down a -> Bool # | |
RealFrac a => RealFrac (Down a) | Since: base-4.14.0.0 |
Show a => Show (Down a) | This instance would be equivalent to the derived instances of the
Since: base-4.7.0.0 |
Ix a => Ix (Down a) | Since: base-4.14.0.0 |
Generic (Down a) | Since: base-4.12.0.0 |
Semigroup a => Semigroup (Down a) | Since: base-4.11.0.0 |
Monoid a => Monoid (Down a) | Since: base-4.11.0.0 |
Storable a => Storable (Down a) | Since: base-4.14.0.0 |
Bits a => Bits (Down a) | Since: base-4.14.0.0 |
Defined in Data.Ord (.&.) :: Down a -> Down a -> Down a # (.|.) :: Down a -> Down a -> Down a # xor :: Down a -> Down a -> Down a # complement :: Down a -> Down a # shift :: Down a -> Int -> Down a # rotate :: Down a -> Int -> Down a # setBit :: Down a -> Int -> Down a # clearBit :: Down a -> Int -> Down a # complementBit :: Down a -> Int -> Down a # testBit :: Down a -> Int -> Bool # bitSizeMaybe :: Down a -> Maybe Int # shiftL :: Down a -> Int -> Down a # unsafeShiftL :: Down a -> Int -> Down a # shiftR :: Down a -> Int -> Down a # unsafeShiftR :: Down a -> Int -> Down a # rotateL :: Down a -> Int -> Down a # | |
FiniteBits a => FiniteBits (Down a) | Since: base-4.14.0.0 |
Defined in Data.Ord finiteBitSize :: Down a -> Int # countLeadingZeros :: Down a -> Int # countTrailingZeros :: Down a -> Int # | |
NFData a => NFData (Down a) | Since: deepseq-1.4.0.0 |
Defined in Control.DeepSeq | |
Prim a => Prim (Down a) | |
Defined in Data.Primitive.Types alignment# :: Down a -> Int# # indexByteArray# :: ByteArray# -> Int# -> Down a # readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Down a #) # writeByteArray# :: MutableByteArray# s -> Int# -> Down a -> State# s -> State# s # setByteArray# :: MutableByteArray# s -> Int# -> Int# -> Down a -> State# s -> State# s # indexOffAddr# :: Addr# -> Int# -> Down a # readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, Down a #) # writeOffAddr# :: Addr# -> Int# -> Down a -> State# s -> State# s # setOffAddr# :: Addr# -> Int# -> Int# -> Down a -> State# s -> State# s # | |
Generic1 Down | Since: base-4.12.0.0 |
type Rep (Down a) | |
Defined in GHC.Generics | |
type Rep1 Down | |
Defined in GHC.Generics |
radixSort :: forall v a. (Vec v a, Radix a) => v a -> v a Source #
O(n) Sort vector based on element's Radix
instance with
radix-sort,
(Least significant digit radix sorts variation).
This is a stable sort, one or two extra O(n) worker array are need
depend on how many passes
shall be performed, and a bucketSize
counting bucket are also needed. This sort algorithms performed extremly
well on small byte size types such as Int8
or Word8
, while on larger
type, constant passes may render this algorithm not suitable for small
vectors (turning point around 2^(2*passes)).
Types contain radixs, which can be inspected with radix
during different passes
.
The default instances share a same bucketSize
256, which seems to be a good default.
bucketSize :: a -> Int Source #
The size of an auxiliary array, i.e. the counting bucket
The number of passes necessary to sort an array of es, it equals to the key's byte number.
The radix function used in the first pass, works on the least significant bit.
radix :: Int -> a -> Int Source #
The radix function parameterized by the current pass (0 < pass < passes e-1).
The radix function used in the last pass, works on the most significant bit.
Similar to Down
newtype for Ord
, this newtype can inverse the order of a Radix
instance when used in radixSort
.
Instances
Eq a => Eq (RadixDown a) Source # | |
Show a => Show (RadixDown a) Source # | |
Prim a => Prim (RadixDown a) Source # | |
Defined in Z.Data.Vector.Sort sizeOf# :: RadixDown a -> Int# # alignment# :: RadixDown a -> Int# # indexByteArray# :: ByteArray# -> Int# -> RadixDown a # readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, RadixDown a #) # writeByteArray# :: MutableByteArray# s -> Int# -> RadixDown a -> State# s -> State# s # setByteArray# :: MutableByteArray# s -> Int# -> Int# -> RadixDown a -> State# s -> State# s # indexOffAddr# :: Addr# -> Int# -> RadixDown a # readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, RadixDown a #) # writeOffAddr# :: Addr# -> Int# -> RadixDown a -> State# s -> State# s # setOffAddr# :: Addr# -> Int# -> Int# -> RadixDown a -> State# s -> State# s # | |
Radix a => Radix (RadixDown a) Source # | |
merge duplicated
mergeDupAdjacent :: (Vec v a, Eq a) => v a -> v a Source #
merge duplicated adjacent element, prefer left element.
Use this function on a sorted vector will have the same effects as nub
.
Merge duplicated adjacent element, prefer left element.
mergeDupAdjacentRight Source #
Merge duplicated adjacent element, prefer right element.