簡體   English   中英

您可以為基數排序制定一個monoid或半群嗎?

[英]Can you formulate a monoid or semigroup for the radix sort?

這是基數排序的偽代碼:

Pseudocode for Radix Sort:
Radix-Sort(A, d)
// Each key in A[1..n] is a d-digit integer. (Digits are
// numbered 1 to d from right to left.)
1. for i = 1 to d do
Use a stable sorting algorithm to sort A on digit i.

這是基數排序的Scala代碼:

object RadixSort {
  val WARP_SIZE = 32

  def main(args: Array[String]) = {
    var A = Array(123,432,654,3123,654,2123,543,131,653,123)

    radixSortUintHost(A, 4).foreach(i => println(i))
  }

  // LSB radix sort
  def radixSortUintHost(A: Array[Int], bits: Int): Array[Int] = {
    var a = A
    var b = new Array[Int](a.length)

    var rshift = 0
    var mask = ~(-1 << bits)

    while (mask != 0) {
      val cntArray = new Array[Int](1 << bits)

      for (p <- 0 until a.length) {
        var key = (a(p) & mask) >> rshift
        cntArray(key)+= 1
      }

      for (i <- 1 until cntArray.length)
        cntArray(i) += cntArray(i-1)

      for (p <- a.length-1 to 0 by -1) {
        var key = (a(p) & mask) >> rshift
        cntArray(key)-= 1
        b(cntArray(key)) = a(p)
      }

      val temp = b
      b = a
      a = temp

      mask <<= bits
      rshift += bits
    }

    b
  }
}

這是基數排序的Haskell代碼:

import Data.Bits (Bits(testBit, bitSize))
import Data.List (partition)

lsdSort :: (Ord a, Bits a) => [a] -> [a]
lsdSort = fixSort positiveLsdSort

msdSort :: (Ord a, Bits a) => [a] -> [a]
msdSort = fixSort positiveMsdSort

-- Fix a sort that puts negative numbers at the end, like positiveLsdSort and positiveMsdSort
fixSort sorter list = uncurry (flip (++)) (break (< 0) (sorter list))

positiveLsdSort :: (Bits a) => [a] -> [a]
positiveLsdSort list = foldl step list [0..bitSize (head list)] where
step list bit = uncurry (++) (partition (not . flip testBit bit) list)

positiveMsdSort :: (Bits a) => [a] -> [a]
positiveMsdSort list = aux (bitSize (head list) - 1) list where
aux _ [] = []
aux (-1) list = list
aux bit list = aux (bit - 1) lower ++ aux (bit - 1) upper where
    (lower, upper) = partition (not . flip testBit bit) list

我的問題是: 您可以為基數排序制定一個monoid或半群嗎?

基數排序不變式是使用前k位對數據進行排序。 如果要添加或不添加更多排序數據的操作,則要求合並排序功能而不是基數。 如果要添加的是所有記錄中的數據位,則可以使用monoid。

編輯:monoid的哈特是一個關聯操作。 我們可以將排序位視為應用部分順序的一種方式。 您會一點一點地傷害所有記錄的數據。 每一位應用部分順序。 這是關聯的,您可以合並一些位以獲得更詳細的部分順序。 音符順序很重要,但仍具有關聯性,因此可以看作一個單子

我認為您可能從字面上考慮了基數排序的想法。 抽象地講,我想您想要的類半身像是

  1. 排序清單
  2. 合並中

最大的問題是您如何表示排序后的列表。 如果將它們表示為已排序的Haskell列表,則合並操作是合並排序中常用的逐段合並。 如果您以更“基調”的方式表示它們,那么您將擁有各種特里 您可能會發現一些合並嘗試的算法。 bytestring-trie有一個,但是關於它的實現似乎沒有任何文獻記載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM