Kotlin:排序 |交换操作的位置

Kotlin: Sorting | Location of swap operation

我正在 Kotlin 中实现快速排序算法。为此,我创建了一个接口 ISort,带有一个类型参数和一个函数 sort。为了排序,我需要交换操作。我想知道这个交换功能的最佳位置是什么。我的想法:

1) 不幸的是,在 Kotlin 中不能使接口函数受到保护。因此,每个 class 都可以在其实现中看到交换,这不是太好(虽然也不是太糟糕,我同意)。

2) 将它放在 QuickSort 实现中更糟糕,因为可能有多个 ISort 接口的实现需要交换函数。

3) 我的下一个想法是创建一个单例对象,但 Kotlin 允许带有类型参数的对象。

接口定义如下:

interface ISort<T> {
  fun sort(toSort: MutableList<T>): MutableList<T>
  // 1) Putting swap here has a too high visibility
}

这是快速排序的框架class:

class QuickSort<T> : ISort<T> {
  override fun sort(toSort: MutableList<T>): MutableList<T> {
    doQuickSort(toSort) // Internally uses swap
    return toSort
  }
  // 2) Putting swap here might lead to code duplication of swap
}

因此,从软件工程的角度来看,交换操作的最佳地点/位置是什么。

顶级函数

在文件 sort.kt 左右,

package abc.def.sort


fun <T> quicksort(list: MutableList<T>): MutableList<T> {
    ...
}

// invisible in other files, but visibie in "sort.kt"
private fun <T> swap(...) {
    ...
}

要在其他排序中使用 swap 函数,您需要在同一文件中定义其他排序函数。 (或者多次复制swap函数。)

推荐用于非常简单的函数。

作为命名空间的对象

这与上面的方法类似,但比上一个更符合 OOP。

object QuickSort {
    fun <T> sort(list: MutableList<T>): MutableList<T> {
        ...
    }

    private fun <T> swap(...) {
        ...
    }
}

object Sorts {
    fun <T> quicksort(list: MutableList<T>): MutableList<T> {
        ...
    }

    // add other sort methods...

    private fun <T> swap(...) {
        ...
    }
}

但是,在 Kotlin (Best practices for top-level declarations) 中不推荐这样做。

抽象class和对象

的组合

swap 函数可以通过这种方式重复用于其他排序。

abstract class Sort {
    abstract fun <T> sort(list: MutableList<T>): MutableList<T>

    protected fun <T> swap(...) {
        ...
    }
}

object QuickSort : Sort() {
    override fun <T> sort(list: MutableList<T>): MutableList<T> {
        ...
    }
}

我认为[使类型参数 T 成为 class 类型参数,而不是函数类型参数] 会使问题不必要地变得更加复杂,因为您将不得不创建一个 class 每次使用不同类型的实例 T.