尝试通过Golang实现一个简单的冒泡排序,以便于后续使用。
原理剖析:
冒泡排序是一种简单的排序算法,其基本原理是通过多次遍历待排序的数组,每次比较相邻的两个元素,并根据需要交换它们的位置,从而使较大的元素逐渐“冒泡”到数组的末尾。这个过程会重复进行,直到整个数组有序为止。
冒泡排序的步骤:
- 初始化:设置一个标志变量
swapped
,用于检测在某次遍历中是否发生了交换。 - 外层循环:遍历数组的每一个元素(除了最后一个,因为最后一个元素在前面的遍历中已经被排序好)。
- 内层循环:在每次外层循环中,遍历数组的未排序部分,比较相邻的两个元素。如果前一个元素大于后一个元素,则交换它们的位置,并将
swapped
标志设置为true
。 - 提前退出:如果在某次外层循环中没有发生任何交换,则说明数组已经有序,可以提前退出循环。
1.定义一个回调函数类型
后续我们将会通过这个回调函数来实现函数的交换判断
type compare func(a interface{}, b interface{}) bool//定义一个回调函数类型
2.开始编写对应的函数(详见注释)
func BubbleSort(arr []interface{}, op compare) {
n := len(arr)//初始化对应的数组长度
swapped := false//初始化交换标记
for i := 0; i < n-1; i++ {//这里的n-1是因为最后一个元素不需要再进行比较
for j := 0; j < n-1-i; j++ {//这里的n-1-i是因为每次比较都会将最大
//的元素放到最后,所以不需要再进行比较
if res := op(arr[j], arr[j+1]); res {//通过回调函数比较两个元素
arr[j], arr[j+1] = arr[j+1], arr[j]//交换两个元素
swapped = true//发生了交换并进行标记
}
}
// 如果没有发生交换,提前退出循环
if !swapped {
break
}
}
}
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:20},
Person{Name:"B", Age:10},
Person{Name:"C", Age:30},
Person{Name:"D", Age:40},
Person{Name:"E", Age:50},
}
fmt.Println("Before Sorting")
for _,v := range arrays{
fmt.Println(v)
}
api.BubbleSort(arrays,compare)
fmt.Println("After Sorting")
for _,v := range arrays{
fmt.Println(v)
}
}