## ===================== LATIHAN MATERI 3 =====================
## ---------- Fungsi umum ----------
tukar <- function(x, a, b) { t <- x[a]; x[a] <- x[b]; x[b] <- t; x }
# Selection sort menurun (seleksi maksimum) + larik tiap pass
sel_max <- function(x, trace = TRUE) {
n <- length(x); banding <- 0; tuker <- 0
for (i in 1:(n - 1)) {
idx <- i
for (j in (i + 1):n) {
banding <- banding + 1
if (x[j] > x[idx]) idx <- j
}
if (idx != i) { x <- tukar(x, i, idx); tuker <- tuker + 1 }
if (trace) cat("Pass", i, ":", x, "\n")
}
list(hasil = x, banding = banding, tukar = tuker)
}
# Selection sort menurun (seleksi minimum -> dipindah ke belakang)
sel_min <- function(x, trace = TRUE) {
n <- length(x)
for (p in 1:(n - 1)) {
last <- n - p + 1
idx <- 1
for (j in 2:last) if (x[j] < x[idx]) idx <- j
if (idx != last) x <- tukar(x, idx, last)
if (trace) cat("Pass", p, ":", x, "\n")
}
x
}
# Insertion sort + hitung perbandingan & pergeseran
ins_sort <- function(x, desc = FALSE) {
banding <- 0; geser <- 0
for (i in 2:length(x)) {
key <- x[i]; j <- i - 1
while (j >= 1) {
banding <- banding + 1
if ((!desc && x[j] > key) || (desc && x[j] < key)) {
x[j + 1] <- x[j]; geser <- geser + 1; j <- j - 1
} else break
}
x[j + 1] <- key
}
list(hasil = x, banding = banding, geser = geser)
}
# Binary insertion sort + hitung perbandingan & pergeseran
bin_ins <- function(x, desc = FALSE) {
banding <- 0; geser <- 0
for (i in 2:length(x)) {
key <- x[i]; lo <- 1; hi <- i - 1
while (lo <= hi) {
mid <- (lo + hi) %/% 2
banding <- banding + 1
if ((!desc && key < x[mid]) || (desc && key > x[mid])) hi <- mid - 1
else lo <- mid + 1
}
if (lo < i) { x[(lo + 1):i] <- x[lo:(i - 1)]; geser <- geser + (i - lo) }
x[lo] <- key
}
list(hasil = x, banding = banding, geser = geser)
}
## ---------- Soal 1 ----------
d1 <- c(25, 22, 18, 20, 15)
cat("== Seleksi Maksimum ==\n"); sel_max(d1)
## == Seleksi Maksimum ==
## Pass 1 : 25 22 18 20 15
## Pass 2 : 25 22 18 20 15
## Pass 3 : 25 22 20 18 15
## Pass 4 : 25 22 20 18 15
## $hasil
## [1] 25 22 20 18 15
##
## $banding
## [1] 10
##
## $tukar
## [1] 1
cat("== Seleksi Minimum ==\n"); sel_min(d1)
## == Seleksi Minimum ==
## Pass 1 : 25 22 18 20 15
## Pass 2 : 25 22 20 18 15
## Pass 3 : 25 22 20 18 15
## Pass 4 : 25 22 20 18 15
## [1] 25 22 20 18 15
## ---------- Soal 2 ----------
a <- ins_sort(c(5, 4, 3, 2, 1)); print(a) # banding 10, geser 10
## $hasil
## [1] 1 2 3 4 5
##
## $banding
## [1] 10
##
## $geser
## [1] 10
b <- ins_sort(c(1, 2, 3, 5, 4)); print(b) # banding 5, geser 1
## $hasil
## [1] 1 2 3 4 5
##
## $banding
## [1] 5
##
## $geser
## [1] 1
## ---------- Soal 3 (bukti selection sort tidak stabil) ----------
rec <- data.frame(nama = c("A", "B", "C"), nilai = c(5, 5, 3))
sel_stabil <- function(df) {
n <- nrow(df)
for (i in 1:(n - 1)) {
idx <- i
for (j in (i + 1):n) if (df$nilai[j] < df$nilai[idx]) idx <- j
if (idx != i) { t <- df[i, ]; df[i, ] <- df[idx, ]; df[idx, ] <- t }
}
df
}
print(rec); print(sel_stabil(rec)) # hasil: C, B, A -> urutan A,B terbalik
## nama nilai
## 1 A 5
## 2 B 5
## 3 C 3
## nama nilai
## 1 C 3
## 2 B 5
## 3 A 5
## ---------- Soal 4 ----------
x4 <- c(5, 4, 3, 2, 1)
r_biasa <- ins_sort(x4)
r_binary <- bin_ins(x4)
cat("Insertion biasa : banding =", r_biasa$banding, " geser =", r_biasa$geser, "\n")
## Insertion biasa : banding = 10 geser = 10
cat("Binary insertion: banding =", r_binary$banding, " geser =", r_binary$geser, "\n")
## Binary insertion: banding = 6 geser = 10
# perbandingan turun, pergeseran sama
## ---------- Soal 5 ----------
cac <- as.numeric(EuStockMarkets[1:50, "CAC"])
s <- sel_max(cac, trace = FALSE)
i <- ins_sort(cac, desc = TRUE)
bi <- bin_ins(cac, desc = TRUE)
hasil <- data.frame(
Metode = c("Selection sort", "Insertion sort", "Binary insertion"),
Perbandingan = c(s$banding, i$banding, bi$banding),
`Pergeseran/Pertukaran` = c(s$tukar, i$geser, bi$geser),
check.names = FALSE
)
print(hasil)
## Metode Perbandingan Pergeseran/Pertukaran
## 1 Selection sort 1225 47
## 2 Insertion sort 1069 1031
## 3 Binary insertion 210 1031
stopifnot(identical(s$hasil, i$hasil), identical(s$hasil, sort(cac, decreasing = TRUE)))