sort.Slice
P1093 [NOIP2007 普及组] 奖学金
题目链接https://www.luogu.com.cn/problem/P1093
解法:从0开始
package main
import (
"fmt"
"sort"
)
type Student struct {
id int
score1, score2, score3 int
sum int
}
func main() {
var stu [305]Student
var n int
fmt.Scan(&n)
for i := 0; i < n; i++ {
fmt.Scan(&stu[i].score1, &stu[i].score2, &stu[i].score3)
stu[i].sum = stu[i].score1 + stu[i].score2 + stu[i].score3
stu[i].id = i + 1
}
//for i := 0; i < n; i++ {
// fmt.Printf("%d, %d, %d, %d, %d\n", stu[i].id, stu[i].score1, stu[i].score2, stu[i].score3, stu[i].sum)
//}
sort.Slice(stu[:n], func(i, j int) bool {
if stu[i].sum != stu[j].sum {
return stu[i].sum > stu[j].sum
} else if stu[i].score1 != stu[j].score1 {
return stu[i].score1 > stu[j].score1
} else {
return stu[i].id < stu[j].id
}
})
for i := 0; i < 5; i++ {
fmt.Printf("%d %d", stu[i].id, stu[i].sum)
if i != 5-1 {
fmt.Printf("\n")
}
}
}
冒泡排序
P1093 [NOIP2007 普及组] 奖学金
题目链接https://www.luogu.com.cn/problem/P1093
解法:从0开始
package main
import (
"fmt"
)
type Student struct {
id int
score1, score2, score3 int
sum int
}
func main() {
var stu [305]Student
var n int
fmt.Scan(&n)
for i := 0; i < n; i++ {
fmt.Scan(&stu[i].score1, &stu[i].score2, &stu[i].score3)
stu[i].sum = stu[i].score1 + stu[i].score2 + stu[i].score3
stu[i].id = i + 1
}
//for i := 0; i < n; i++ {
// fmt.Printf("%d, %d, %d, %d, %d\n", stu[i].id, stu[i].score1, stu[i].score2, stu[i].score3, stu[i].sum)
//}
for i := 0; i < n-1; i++ { //遍历次数
for j := 0; j < n-1-i; j++ { //位置
if stu[j].sum != stu[j+1].sum {
if stu[j].sum < stu[j+1].sum {
stu[j], stu[j+1] = stu[j+1], stu[j]
}
} else if stu[j].score1 != stu[j+1].score1 {
if stu[j].score1 < stu[j+1].score1 {
stu[j], stu[j+1] = stu[j+1], stu[j]
}
} else if stu[j].id > stu[j+1].id {
stu[j], stu[j+1] = stu[j+1], stu[j]
}
}
}
for i := 0; i < 5; i++ {
fmt.Printf("%d %d", stu[i].id, stu[i].sum)
if i != 5-1 {
fmt.Printf("\n")
}
}
}
快速排序
partition1
下标从0开始,从小到大排序
func quickSort(arr []int, left, right int) {
if left < right {
pos := partition1(arr, left, right)
quickSort(arr, left, pos-1)
quickSort(arr, pos+1, right)
}
}
func partition1(arr []int, left, right int) int {
//选取最后一个元素作为基准pivot
pivot := arr[right]
pos := left
//最后一个值就是基准,所以不用比较
for i := left; i < right; i++ {
if arr[i] <= pivot {
arr[i], arr[pos] = arr[pos], arr[i] //swap(),
pos += 1 //pos之前(不包括pos,pos位置不确定)都是比pivot基准值小的,只有比基准值小的是否,才跟pos位置交换
}
}
//把基准值换到中间
arr[right], arr[pos] = arr[pos], arr[right]
return pos
}
func main() {
arr := []int{5, 8, 2, 1, 4, 3, 6, 2}
quickSort(arr, 0, len(arr)-1)
fmt.Println(arr)
}
partition2
下标从0开始,从小到大排序
func quickSort(arr []int, left, right int) {
if left < right {
pos := partition2(arr, left, right)
quickSort(arr, left, pos-1)
quickSort(arr, pos+1, right)
}
}
func partition2(arr []int, left, right int) int {
//选取最后一个元素作为基准pivot
pivot := arr[right]
l, r := left, right
for l < r {
//因为把pivot放在最后,所以先让l指针先走
for l < r && arr[l] <= pivot { // 注意有等于号
l += 1
}
for l < r && arr[r] >= pivot {
r -= 1
}
if l < r {
arr[l], arr[r] = arr[r], arr[l]
}
}
//把基准值换到中间
arr[right], arr[l] = arr[l], arr[right]
return l
}
func main() {
arr := []int{5, 8, 2, 1, 4, 3, 6, 2}
quickSort(arr, 0, len(arr)-1)
fmt.Println(arr)
}
P1093 [NOIP2007 普及组] 奖学金
题目链接https://www.luogu.com.cn/problem/P1093
解法:从0开始
package main
import "fmt"
type Student struct {
id int
score1, score2, score3 int
sum int
}
func quickSort(stu []Student, left, right int) {
if left < right {
pos := partition2(stu, left, right)
quickSort(stu, left, pos-1)
quickSort(stu, pos+1, right)
}
}
//1:stu1>stu2; 0:stu1<stu2;
func compareStudent(stu1, stu2 Student) int {
if stu1.sum != stu2.sum {
if stu1.sum > stu2.sum {
return 1
} else {
return 0
}
} else if stu1.score1 != stu2.score1 {
if stu1.score1 > stu2.score1 {
return 1
} else {
return 0
}
} else {
if stu1.id < stu2.id {
return 1
} else {
return 0
}
}
}
func partition2(stu []Student, left, right int) int {
//fmt.Printf("%d, %d\n", left, right)
//选取最后一个元素作为基准pivot
pivot := stu[right]
l, r := left, right
for l < r {
//因为把pivot放在最后,所以先让l指针先走
for l < r && (compareStudent(stu[l], pivot) == 1 || stu[l].id == pivot.id) {
l += 1
}
for l < r && (compareStudent(stu[r], pivot) == 0 || stu[r].id == pivot.id) {
r -= 1
}
if l < r {
stu[l], stu[r] = stu[r], stu[l]
}
}
//把基准值换到中间
stu[right], stu[l] = stu[l], stu[right]
return l
}
func main() {
var stu [305]Student
var n int
fmt.Scan(&n)
for i := 0; i < n; i++ {
fmt.Scan(&stu[i].score1, &stu[i].score2, &stu[i].score3)
stu[i].sum = stu[i].score1 + stu[i].score2 + stu[i].score3
stu[i].id = i + 1
}
//fmt.Println(stu[:n])
quickSort(stu[:n], 0, n-1)
for i := 0; i < 5; i++ {
fmt.Printf("%d %d", stu[i].id, stu[i].sum)
if i != 5-1 {
fmt.Printf("\n")
}
}
}
归并排序
P1177 【模板】排序
https://www.luogu.com.cn/problem/P1177
从0开始
package main
import "fmt"
func Merge(arr []int, left, right, mid int) {
arrTemp := make([]int, right-left+1)
for k := left; k <= right; k++ {
arrTemp[k-left] = arr[k]
}
i, j := left, mid+1
for k := left; k <= right; k++ {
if i > mid {
arr[k] = arrTemp[j-left]
j++
} else if j > right {
arr[k] = arrTemp[i-left]
i++
} else if arrTemp[i-left] > arrTemp[j-left] {
arr[k] = arrTemp[j-left]
j++
} else {
arr[k] = arrTemp[i-left]
i++
}
}
}
func MergeSort(arr []int, left, right int) {
if left >= right {
return
}
mid := (left + right) / 2
MergeSort(arr, left, mid) //[]
MergeSort(arr, mid+1, right)
Merge(arr, left, right, mid)
}
func main() {
var n int
fmt.Scan(&n)
arr := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scan(&arr[i])
}
MergeSort(arr, 0, n-1)
for i := 0; i < n; i++ {
fmt.Printf("%d", arr[i])
if i != n-1 {
fmt.Printf(" ")
}
}
}
堆排序
P1177 【模板】排序
https://www.luogu.com.cn/problem/P1177
从0开始
大根堆
package main
import "fmt"
func shiftdown(arr []int, n int, pos int) {
for {
lchild := pos*2 + 1
rchild := pos*2 + 2
idx := pos
if lchild < n && arr[lchild] > arr[idx] {
idx = lchild
}
if rchild < n && arr[rchild] > arr[idx] {
idx = rchild
}
if idx == pos {
break
}
arr[idx], arr[pos] = arr[pos], arr[idx] //swap
pos = idx
}
}
func HeapSort(arr []int) {
//建立大根堆
for i := len(arr)/2 - 1; i >= 0; i-- {
shiftdown(arr, len(arr), i)
}
//交换arr[0]和arr[len(a)-1],然后把前面这段数组继续下沉保持大根堆,循环操作
for i := len(arr) - 1; i >= 1; i-- {
arr[0], arr[i] = arr[i], arr[0]
shiftdown(arr, i, 0) // 注意这堆的长度要一点点缩小
}
}
func main() {
var n int
fmt.Scan(&n)
arr := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scan(&arr[i])
}
HeapSort(arr)
for i := 0; i < n; i++ {
fmt.Printf("%d", arr[i])
if i != n-1 {
fmt.Printf(" ")
}
}
}
小根堆
package main
import "fmt"
func shiftdown(arr []int, n int, pos int) {
for {
lchild := pos*2 + 1
rchild := pos*2 + 2
idx := pos
if lchild < n && arr[lchild] < arr[idx] {
idx = lchild
}
if rchild < n && arr[rchild] < arr[idx] {
idx = rchild
}
if idx == pos {
break
}
arr[idx], arr[pos] = arr[pos], arr[idx] //swap
pos = idx
}
}
func HeapSort2(arr []int) {
//建立小根堆
for i := len(arr)/2 - 1; i >= 0; i-- {
shiftdown(arr, len(arr), i)
}
//每次取出小根堆的根,就是最小值,和最后一个互换,然后缩小堆的大小,正序就是从大到小,倒序就是从小到大
for i := 0; i < len(arr)-1; i++ {
arr[0], arr[len(arr)-1-i] = arr[len(arr)-1-i], arr[0]
shiftdown(arr, len(arr)-1-i, 0)
}
}
func main() {
var n int
fmt.Scan(&n)
arr := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scan(&arr[i])
}
HeapSort2(arr)
for i := n - 1; i >= 0; i-- {
fmt.Printf("%d", arr[i])
if i != 0 {
fmt.Printf(" ")
}
}
}