import javafx.animation.AnimationTimer
import javafx.collections.FXCollections
import javafx.scene.paint.Color
import javafx.scene.shape.Rectangle
import tornadofx.*
import java.lang.Thread.sleep
class 选择排序 : App(选择排序V::class)
class 选择排序V : View("learn 选择排序") {
// 每个矩形宽度
val w = 10.0
// 100个矩形容器
val rec = FXCollections.observableArrayList<Rectangle>()
// 动画计时器
val aniTimer =AniTimer()
val result = stringProperty()
val swapNum = stringProperty()
val N = 100
val randomBound = 400
val data0 = SelectionSortData(N, randomBound)
val delay0 = 1L
override val root = borderpane {
top = vbox(5) {
result.value = "result:${data0.numbers.toString()}"
label(result) {
isWrapText = true
}
label(swapNum)
hbox(5) {
button("run").action {
// aniTimer.start()
run {
aniTimer.start()
}
}
button("stop").action {
aniTimer.stop()
}
}
}
center = group {
(1..N).forEach {
val r = rectangle(w * it, 200.0, w - 2, data0.numbers[N - it]) {
fill = Color.GRAY
}
rec.add(r)
}
rotate = 180.0
}
prefHeight = 800.0
prefWidth = 1000.0
}
fun paint() {
setData(0, -1, -1)
for (i in data0.numbers.indices) {
var minIndex = i
rec[minIndex].fill = Color.INDIGO
setData(i, -1, minIndex)
var j = i + 1
if (j < data0.N()) {
(j..data0.N()).map {
setData(i, j, minIndex)
if (data0.get(j) > data0.get(minIndex)) {
rec[j].fill = Color.LIGHTBLUE
rec[minIndex].fill = Color.LIGHTBLUE
swapNum.value =
"当前比较的数:j:${j}:${data0.get(j)} -- ${data0.orderedIndex} -- ${j}:${data0.get(j)}--${minIndex}:${data0.get(
minIndex
)}"
minIndex = j
rec[minIndex].fill = Color.INDIGO
setData(i, j, minIndex)
}
}
}
data0.swap(i, minIndex)
setData(i+1, -1, -1)
rec[i].height=data0.numbers[i].toDouble()
rec[minIndex].height=data0.numbers[minIndex].toDouble()
sleep(delay0)
result.value = "result:${data0.numbers.reversed()}"
}
setData(data0.N(), -1, -1)
}
fun setData(orderedIndex: Int, currentCompareIndex: Int, currentMinIndex: Int) {
data0.orderedIndex = orderedIndex
data0.currentCompareIndex = currentCompareIndex
data0.currentMinIndex = currentMinIndex
// if(orderedIndex in (0..N-1)) {
// (orderedIndex..N-1).map{
// rec[it].fill = Color.RED
// }
// }
// if(currentCompareIndex in (0..N-1)) {
// rec[currentCompareIndex].fill = Color.LIGHTBLUE
// }
// if(currentMinIndex in (0..N-1)) {
// rec[currentMinIndex].fill = Color.INDIGO
// }
// if (i == data0.currentCompareIndex) rec[i].fill = Color.LIGHTBLUE
// if (i == data0.currentMinIndex) rec[i].fill = Color.INDIGO
}
// 此方法可以停止动画
inner class AniTimer: AnimationTimer() {
var lastTime = 0L
override fun handle(now: Long) {
if ((now - lastTime) > 10000000) {
lastTime = now
} else {
return
}
paint()
}
}
}
class SelectionSortData {
val numbers = ArrayList<Int>()
// [0..orderedIndex)是有序的
var orderedIndex = -1
// 当前找到的最小元素的索引
var currentMinIndex = -1
// 当前正在比较的元素的索引
var currentCompareIndex = -1
constructor(N: Int, randomBound: Int) {
(1..N).map { numbers.add((1..randomBound).random()) }
}
fun N() = numbers.size
fun get(i: Int) = numbers[i]
fun swap(i: Int, j: Int) {
val t = numbers[i]
numbers[i] = numbers[j]
numbers[j] = t
}
}