排序和查找

排序是将一组数据,依指定的顺序进行排序的过程。

一、排序的分类

内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。包括交换排序、选择排序和插入排序。
外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括合并排序和直接合并排序。

二、排序

1、冒泡排序

通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移向前部(从下标较大的单元移向下标较小的单元)。
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排查过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较(优化)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
 
import "fmt"
 
func BubbleSort(arr *[5]int) {
    fmt.Println("排序前arr= ", (*arr))
 
    for i := 0; i < len(*arr)-1; i++ {
        for j := 0; j < len(*arr)-1-i; j++ {
            if (*arr)[j] > (*arr)[j+1] {
                (*arr)[j+1] = (*arr)[j+1] + (*arr)[j]
                (*arr)[j] = (*arr)[j+1] - (*arr)[j]
                (*arr)[j+1] = (*arr)[j+1] - (*arr)[j]
            }
        }
    }
    fmt.Println("排序后arr= ", (*arr))
}
 
func main() {
    arr := [5]int{2, 4, 1, 9, 8}
    BubbleSort(&arr)
    fmt.Println("main arr= ", arr)
}

2、选择排序

选择排序(select sorting)也是一种简单的排序方法。它的基本思想是:第一次从R[0]~R[n-1]中选 取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,第三次从R[2]~R[n-1]中选取最小值,与 R[2]交换,...,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,..., 第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main
 
import "fmt"
 
func SelectSort(arr *[9]int) {
    //(*arr)[1]=600 等价于 arr[1]=600
 
    for i := 0; i < len(arr)-1; i++ {
        min := arr[i]
        minIndex := i
        for j := i + 1; j < len(arr); j++ {
            if min > arr[j] {
                min = arr[j]
                minIndex = j
            }
        }
        if minIndex != i {
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
        }
        fmt.Printf("第%d次 %v\n", i+1, *arr)
    }
}
 
func main() {
    var arr [9]int = [9]int{8, 0, 2, 4, 1, 6, 3, 5, 7}
    SelectSort(&arr)
}

3、插入排序

插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个 元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
 
import "fmt"
 
func InsertSort(arr *[9]int) {
    for i := 1; i < len(arr); i++ {
        insertVal := arr[i]
        j := i - 1
        for j >= 0 && arr[j] < insertVal {
            arr[j+1] = arr[j]
            j--
        }
        if j+1 != i {
            arr[j+1] = insertVal
        }
        fmt.Printf("第%d次插入后%v\n", i, *arr)
    }
}
 
func main() {
    var arr [9]int = [9]int{8, 0, 2, 4, 1, 6, 3, 5, 7}
    InsertSort(&arr)
}

4、快速排序

快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main
 
import "fmt"
 
//left表示数组左边的下标,right表示数组右边的下标,pivot表示中轴、支点
func QuickSort(left int, right int, array *[9]int) {
    l := left
    r := right
    pivot := array[(left+right)/2]
    tmp := 0
 
    //将比pivot小的数放到左边,比pivot大的数放到右边
    for ; l < r; {
        //从pivot的左边找到大于等于pivot的值
        for ; array[l] < pivot; {
            l++
        }
        //从pivot的右边边找到小于等于pivot的值
        for ; array[r] > pivot; {
            r--
        }
        //1>=r表明本次分解任务完成
        if l >= r {
            break
        }
        tmp = array[l]
        array[l] = array[r]
        array[r] = tmp
        if array[l] == pivot {
            r--
        }
        if array[r] == pivot {
            l++
        }
    }
    if l == r {
        l++
        r--
    }
    //向左递归
    if left < r {
        QuickSort(left, r, array)
    }
    //向右递归
    if right > l {
        QuickSort(l, right, array)
    }
}
 
func main() {
    var arr [9]int = [9]int{8, 0, 2, 4, 1, 6, 3, 5, 7}
    fmt.Println("初始", arr)
    //调用快速排序
    QuickSort(0, len(arr)-1, &arr)
    fmt.Println("排序后", arr)

三、查找

在golang中常用的查找有两种:顺序查找和二分查找(数组是有序的)。

1、顺序查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main
 
import "fmt"
 
func main() {
    //有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王.从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
 
    //实现方式一
    names := [4]string{"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"}
    var heroName = ""
    fmt.Println("请输入要查找的人名")
    fmt.Scanln(&heroName)
 
    for i := 0; i < len(names); i++ {
        if heroName == names[i] {
            fmt.Printf("找到%v,下标%v\n", heroName, i)
            break
        } else if i == (len(names) - 1) {
            fmt.Printf("没有找到%v\n", heroName)
        }
    }
 
    //实现方式二
    index := -1
    for i := 0; i < len(names); i++ {
        if heroName == names[i] {
            index = i
            break
        }
    }
    if index != -1 {
        fmt.Printf("找到%v,下标%v\n", heroName, index)
    } else {
        fmt.Println("没有找到", heroName)
    }
}

 2、二分查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
 
import "fmt"
 
func BinaryFind(arr *[6]int, leftIndex int, rightIndex int, findVal int) {
    if leftIndex > rightIndex {
        fmt.Println("找不到", findVal)
        return
    }
 
    middle := (leftIndex + rightIndex) / 2
    if (*arr)[middle] > findVal {
        BinaryFind(arr, leftIndex, middle-1, findVal)
    } else if (*arr)[middle] < findVal {
        BinaryFind(arr, middle+1, rightIndex, findVal)
    } else {
        fmt.Printf("找到了%v,下标为%v\n", findVal, middle)
    }
}
 
func main() {
    arr := [6]int{1, 8, 10, 89, 1000, 1234}
 
    BinaryFind(&arr, 0, len(arr)-1, -6)
    BinaryFind(&arr, 0, len(arr)-1, 89)
}

四、二维数组

二维数组在声明/定义时的四种写法[
var 数组名 [大小][大小]类型 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 [大小][大小]类型 = [...][大小]类型{{初值..},{初值..}}
var 数组名 = [大小][大小]类型{{初值..},{初值..}}
var 数组名 = [...][大小]类型{{初值..},{初值..}}

二维数组的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
 
import "fmt"
 
func main() {
    var arr = [2][3]int{{1, 2, 3}, {4, 5, 6}}
 
    //for循环遍历
    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr[i]); j++ {
            fmt.Printf("%v\t", arr[i][j])
        }
        fmt.Println()
    }
 
    //for - range遍历二维数组
    for i, v := range arr {
        for j, v2 := range v {
            fmt.Printf("arr[%v][%v]=%v\t", i, j, v2)
        }
        fmt.Println()
    }
}

定义二维数组,用于保存三个班,每个班五名同学成绩,并求出每个班级平均分、以及所有班级平均分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main
 
import (
    "fmt"
)
 
func main() {
    /*
    定义二维数组,用于保存三个班,每个班五名同学成绩
    并求出每个班级平均分、以及所有班级平均分
     */
    var scores [3][5]float64
 
    for i := 0; i < len(scores); i++ {
        for j := 0; j < len(scores[i]); j++ {
            fmt.Printf("请输入第%d班的第%d个学生的成绩\n", i+1, j+1)
            fmt.Scanln(&scores[i][j])
        }
    }
 
    totalSum := 0.0
    for i := 0; i < len(scores); i++ {
        sum := 0.0
        for j := 0; j < len(scores[i]); j++ {
            sum += scores[i][j]
        }
        totalSum += sum
        fmt.Printf("第%d班的总分为%v,平均分为%v\n", i+1, sum, sum/float64(len(scores[i])))
    }
    fmt.Printf("所有班级的总分是%v,所有班级的平均分是%v\n", totalSum, totalSum/15)
}

 

posted on   lina2014  阅读(210)  评论(0编辑  收藏  举报

编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· 程序员常用高效实用工具推荐,办公效率提升利器!
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 【译】WinForms:分析一下(我用 Visual Basic 写的)

导航

< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示