插入排序的原理
插入排序(Insertion Sort)是一种简单直观的排序算法,其主要思想是通过构建有序序列,将未排序的数据依次插入到已排序的序列中,直到所有元素都排序完毕。它的工作方式类似于整理扑克牌:
- 从第二个元素开始(假设第一个元素已经有序),将当前元素与它前面的所有元素进行比较。
- 找到合适的位置,并将当前元素插入到这个位置。
- 重复上述步骤,直到所有元素都插入到正确的位置。
插入排序的步骤
- 从第一个元素开始,该元素认为是已排序的。
- 取出下一个元素,在已经排序的元素序列中从后向前扫描。
- 如果已排序元素大于新元素,则将已排序元素向后移动一位。
- 重复步骤3,直到找到已排序元素小于或等于新元素的位置。
- 将新元素插入到这个位置中。
- 重复上述过程,直到所有元素排序完成。
代码实现
1.定义一个回调函数类型
type compare func(a interface{}, b interface{}) bool//定义一个回调函数类型
2.开始编写对应的函数(详见注释)
func InsertSort(arr []interface{}, op compare) {
for i := 1; i < len(arr); i++ {
current := arr[i]//保存当前元素
j := i - 1//从当前元素的前一个元素开始比较
// 找到插入位置
for j >= 0 && op(arr[j], current) {
//arr[j],arr[j-1] = arr[j-1],arr[j] 原本使用了交换来
//查找对应的位置,但是这样这样会导致多次不必要的交换操作,
//所以替换为下面的代码进行覆盖式查找插入位置
arr[j+1] = arr[j]//将大于current的元素向后移动,保留出插入的位置
j--
}
// 最终插入元素
arr[j+1] = current
}
}
3.调用测试
type Person struct {
Name string
Age int
}
func (p Person)String()string{
return fmt.Sprintf("Name: %s, Age: %d",p.Name,p.Age)
}
func compare(a interface{}, b interface{}) bool {
return a.(Person).Age > b.(Person).Age
}
func main() {
arrays := []interface{}{
Person{Name:"A", Age:11},
Person{Name:"B", Age:25},
Person{Name:"C", Age:5},
Person{Name:"D", Age:67},
Person{Name:"E", Age:100},
}
fmt.Println("Before Sorting")
for _,v := range arrays{
fmt.Println(v)
}
api.InsertSort(arrays,compare)
fmt.Println("After Sorting")
for _,v := range arrays{
fmt.Println(v)
}
}
4.测试结果
Before Sorting
Name: A, Age: 11
Name: B, Age: 25
Name: C, Age: 5
Name: D, Age: 67
Name: E, Age: 100
After Sorting
Name: C, Age: 5
Name: A, Age: 11
Name: B, Age: 25
Name: D, Age: 67
Name: E, Age: 100