sorting.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 592 行 · 第 1/2 页

SCALA
592
字号
      x(a) = x(b)      x(b) = t    }    def vecswap(_a: Int, _b: Int, n: Int) {      var a = _a      var b = _b      var i = 0      while (i < n) {        swap(a, b)        i += 1        a += 1        b += 1      }    }    def med3(a: Int, b: Int, c: Int) = {      val ab = x(a) compare x(b)      val bc = x(b) compare x(c)      val ac = x(a) compare x(c)      if (ab < 0) {        if (bc < 0) b else if (ac < 0) c else a      } else {        if (bc > 0) b else if (ac > 0) c else a      }    }    def sort2(off: Int, len: Int) {      // Insertion sort on smallest arrays      if (len < 7) {        var i = off        while (i < len + off) {          var j = i          while (j > off && (x(j-1) compare x(j)) > 0) {            swap(j, j-1)            j -= 1          }          i += 1        }      } else {        // Choose a partition element, v        var m = off + (len >> 1)        // Small arrays, middle element        if (len > 7) {          var l = off          var n = off + len - 1          if (len > 40) {        // Big arrays, pseudomedian of 9            var s = len / 8            l = med3(l, l+s, l+2*s)            m = med3(m-s, m, m+s)            n = med3(n-2*s, n-s, n)          }          m = med3(l, m, n) // Mid-size, med of 3        }        val v = x(m)        // Establish Invariant: v* (<v)* (>v)* v*        var a = off        var b = a        var c = off + len - 1        var d = c        var done = false        while (!done) {          var bv = x(b) compare v          while (b <= c && bv <= 0) {            if (bv == 0) {              swap(a, b)              a += 1            }            b += 1            if (b <= c) bv = x(b) compare v          }          var cv = x(c) compare v          while (c >= b && cv >= 0) {            if (cv == 0) {              swap(c, d)              d -= 1            }            c -= 1            if (c >= b) cv = x(c) compare v          }          if (b > c) {            done = true          } else {            swap(b, c)            c -= 1            b += 1          }        }        // Swap partition elements back to middle        val n = off + len        var s = Math.min(a-off, b-a)        vecswap(off, b-s, s)        s = Math.min(d-c, n-d-1)        vecswap(b,   n-s, s)        // Recursively sort non-partition-elements        s = b - a        if (s > 1)          sort2(off, s)        s = d - c        if (s > 1)          sort2(n-s, s)      }    }    sort2(off, len)  }  private def sort1(x: Array[Float], off: Int, len: Int) {    def swap(a: Int, b: Int) {      val t = x(a)      x(a) = x(b)      x(b) = t    }    def vecswap(_a: Int, _b: Int, n: Int) {      var a = _a      var b = _b      var i = 0      while (i < n) {        swap(a, b)        i += 1        a += 1        b += 1      }    }    def med3(a: Int, b: Int, c: Int) = {      val ab = x(a) compare x(b)      val bc = x(b) compare x(c)      val ac = x(a) compare x(c)      if (ab < 0) {        if (bc < 0) b else if (ac < 0) c else a      } else {        if (bc > 0) b else if (ac > 0) c else a      }    }    def sort2(off: Int, len: Int) {      // Insertion sort on smallest arrays      if (len < 7) {        var i = off        while (i < len + off) {          var j = i          while (j > off && (x(j-1) compare x(j)) > 0) {            swap(j, j-1)            j -= 1          }          i += 1        }      } else {        // Choose a partition element, v        var m = off + (len >> 1)        // Small arrays, middle element        if (len > 7) {          var l = off          var n = off + len - 1          if (len > 40) {        // Big arrays, pseudomedian of 9            var s = len / 8            l = med3(l, l+s, l+2*s)            m = med3(m-s, m, m+s)            n = med3(n-2*s, n-s, n)          }          m = med3(l, m, n) // Mid-size, med of 3        }        val v = x(m)        // Establish Invariant: v* (<v)* (>v)* v*        var a = off        var b = a        var c = off + len - 1        var d = c        var done = false        while (!done) {          var bv = x(b) compare v          while (b <= c && bv <= 0) {            if (bv == 0) {              swap(a, b)              a += 1            }            b += 1            if (b <= c) bv = x(b) compare v          }          var cv = x(c) compare v          while (c >= b && cv >= 0) {            if (cv == 0) {              swap(c, d)              d -= 1            }            c -= 1            if (c >= b) cv = x(c) compare v          }          if (b > c) {            done = true          } else {            swap(b, c)            c -= 1            b += 1          }        }        // Swap partition elements back to middle        val n = off + len        var s = Math.min(a-off, b-a)        vecswap(off, b-s, s)        s = Math.min(d-c, n-d-1)        vecswap(b,   n-s, s)        // Recursively sort non-partition-elements        s = b - a        if (s > 1)          sort2(off, s)        s = d - c        if (s > 1)          sort2(n-s, s)      }    }    sort2(off, len)  }  private def stableSort[K](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {    if (lo < hi) {      val mid = (lo+hi) / 2      stableSort(a, lo, mid, scratch, f)      stableSort(a, mid+1, hi, scratch, f)      var k, t_lo = lo      var t_hi = mid + 1      while (k <= hi) {        if ((t_lo <= mid) && ((t_hi > hi) || (f(a(t_lo), a(t_hi))))) {           scratch(k) = a(t_lo)           t_lo += 1         } else {           scratch(k) = a(t_hi)           t_hi += 1         }        k += 1      }      k = lo      while (k <= hi) {        a(k) = scratch(k)        k += 1      }    }  }  // for testing  def main(args: Array[String]) {    val tuples = Array(      (1, "one"), (1, "un"), (3, "three"), (2, "deux"),      (2, "two"), (0, "zero"), (3, "trois")    )    val integers = Array(      3, 4, 0, 4, 5, 0, 3, 3, 0    )    val doubles = Array(      3.4054752250314283E9,      4.9663151227666664E10,      0.0/0.0,      4.9663171987125E10,      5.785996973446602E9,      0.0/0.0,      3.973064849653333E10,      3.724737288678125E10,      0.0/0.0    )    val floats = Array(      3.4054752250314283E9f,      4.9663151227666664E10f,      0.0f/0.0f,      4.9663171987125E10f,      5.785996973446602E9f,      0.0f/0.0f,      3.973064849653333E10f,      3.724737288678125E10f,      0.0f/0.0f    )    Sorting quickSort tuples    println(tuples.toList)    Sorting quickSort integers    println(integers.toList)    Sorting quickSort doubles    println(doubles.toList)    Sorting quickSort floats    println(floats.toList)  }}/** <p> *    A <code>RichSorting</code> object is generally created implicitly through *    the use of the <code>sort</code> function on an arbitrary sequence, where *    the items are ordered. *  </p> */class RichSorting[K <: Ordered[K]](s: Seq[K]) {  /** Returns an array with a sorted copy of the RichSorting's sequence.   */  def sort = Sorting.stableSort(s)}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?