zoukankan      html  css  js  c++  java
  • GO语言系列- 高级数据类型之数组、切片、map

    一、数组和切片

    数组

    • 1. 数组:是同一种数据类型的固定长度的序列。
    • 2. 数组定义:var a [len]int,比如:var a[5]int,一旦定义,长度不能变
    • 3. 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
    • 4. 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1
    for i := 0; i < len(a); i++ {
    }
    for index, v := range a {
    }
    • 5. 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
    • 6. 数组是值类型,因此改变副本的值,不会改变本身的值
    package main
    
    import "fmt"
    
    func test1() {
        var a [10]int
        a[0] = 10
        a[9] = 100
        fmt.Println(a)
    
        for i := 0; i < len(a); i++ {
            fmt.Println(a[i])
        }
        for index, val := range a {
            fmt.Printf("a[%d]=%d
    ", index, val)
        }
    }
    
    func test2() {
        var a [10]int
        b := a
        b[0] = 100
        fmt.Println(a)
    }
    
    func test3(arr *[5]int) {
        (*arr)[0] = 1000
    }
    
    func main() {
        test1()
        test2()
        var a [5]int
        test3(&a)
        fmt.Println(a)
    }
    
    /*
    [10 0 0 0 0 0 0 0 0 100]
    10
    0
    0
    0
    0
    0
    0
    0
    0
    100
    a[0]=10
    a[1]=0
    a[2]=0
    a[3]=0
    a[4]=0
    a[5]=0
    a[6]=0
    a[7]=0
    a[8]=0
    a[9]=100
    [0 0 0 0 0 0 0 0 0 0]
    [1000 0 0 0 0]
    */
    数组示例一

    数组初始化

    a. var age0 [5]int = [5]int{1,2,3}
    b. var age1 = [5]int{1,2,3,4,5}
    c. var age2 = […]int{1,2,3,4,5,6}
    d. var str = [5]string{3:”hello world”, 4:”tom”}

    多维数组

    a. var age [5][3]int
    b. var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}  

    多维数组遍历

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    
    	var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
    
    	for k1, v1 := range f {
    		for k2, v2 := range v1 {
    			fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
    		}
    		fmt.Println()
    	}
    } 

    数组示例

    package main
    
    import (
        "fmt"
    )
    
    func fab(n int) {
        var a []int
        a = make([]int, n)
    
        a[0] = 1
        a[1] = 1
    
        for i := 2; i < n; i++ {
            a[i] = a[i-1] + a[i-2]
        }
    
        for _, v := range a {
            fmt.Println(v)
        }
    }
    
    func testArray() {
        var a [5]int = [5]int{1, 2, 3, 4, 5}
        var a1 = [5]int{1, 2, 3, 4, 5}
        var a2 = [...]int{38, 283, 48, 38, 348, 387, 484}
        var a3 = [...]int{1: 100, 3: 200}
        var a4 = [...]string{1: "hello", 3: "world"}
    
        fmt.Println(a)
        fmt.Println(a1)
        fmt.Println(a2)
        fmt.Println(a3)
        fmt.Println(a4)
        /*
            [1 2 3 4 5]
            [1 2 3 4 5]
            [38 283 48 38 348 387 484]
            [0 100 0 200]
            [ hello  world]
        */
    }
    
    func testArray2() {
        var a [2][5]int = [...][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}
    
        for row, v := range a {
            for col, v1 := range v {
                fmt.Printf("(%d,%d)=%d ", row, col, v1)
            }
            fmt.Println()
        }
    }
    
    func main() {
        fab(10)
        testArray()
        testArray2()
    }
    数组示例二

    切片

    1. 切片相关概念

    • 1. 切片:切片是数组的一个引用,因此切片是引用类型
    • 2. 切片的长度可以改变,因此,切片是一个可变的数组
    • 3. 切片遍历方式和数组一样,可以用len()求长度
    • 4. cap可以求出slice最大的容量,0 <= len(slice) <= (array),其中array是slice引用的数组
    • 5. 切片的定义:var 变量名 []类型,比如 var str []string var arr []int

    2. 切片的相关语法

    • 1. 切片初始化:var slice []int = arr[start:end] 包含start到end之间的元素,但不包含end
    • 2. Var slice []int = arr[0:end]可以简写为 var slice []int=arr[:end]
    • 3. Var slice []int = arr[start:len(arr)] 可以简写为 var slice[]int = arr[start:]
    • 4. Var slice []int = arr[0, len(arr)] 可以简写为 var slice[]int = arr[:]
    • 5. 如果要切片最后一个元素去掉,可以这么写: Slice = slice[:len(slice)-1]

    3. 切片的内存布局

    4. 通过make来创建切片

    var slice []type = make([]type, len)
    slice := make([]type, len)
    slice := make([]type, len, cap)

    5. 用append内置函数操作切片

    slice = append(slice, 10)
    var a = []int{1,2,3}
    var b = []int{4,5,6}
    a = append(a, b…)

    6. For range 遍历切片

    for index, val := range slice {
    }

    7. 切片resize

    var a = []int {1,3,4,5}
    b := a[1:2]
    b = b[0:3]

    8. 切片拷贝

    s1 := []int{1,2,3,4,5}
    
    s2 := make([]int, 10)
    
    copy(s2, s1)
    
    s3 := []int{1,2,3}
    
    s3 = append(s3, s2…)
    
    s3 = append(s3, 4,5,6)

    9. string与slice

      string底层就是一个byte的数组,因此,也可以进行切片操作

    str := “hello world”
    s1 := str[0:5]
    fmt.Println(s1)
    s2 := str[5:]
    fmt.Println(s2)

    10. string的底层布局

    11. 如何改变string中的字符值?

    string本身是不可变的,因此要改变string中字符,需要如下操作:

    str := “hello world”
    s := []byte(str)
    s[0] = ‘o’
    str = string(s)

    12. 排序和查找操作

    排序操作主要都在 sort包中,导入就可以使用了

    sort.Ints对整数进行排序, sort.Strings对字符串进行排序, sort.Float64s对
    浮点数进行排序.
    sort.SearchInts(a []int, b int) 从数组a中查找b,前提是a必须有序
    sort.SearchFloats(a []float64, b float64) 从数组a中查找b,前提是a必须有序
    sort.SearchStrings(a []string, b string) 从数组a中查找b,前提是a必须有序

    13. 切片的扩容机制

    可以通过查看$GOROOT/src/runtime/slice.go源码,其中扩容相关代码如下:

    newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {
    	newcap = cap
    } else {
    	if old.len < 1024 {
    		newcap = doublecap
    	} else {
    		// Check 0 < newcap to detect overflow
    		// and prevent an infinite loop.
    		for 0 < newcap && newcap < cap {
    			newcap += newcap / 4
    		}
    		// Set newcap to the requested cap when
    		// the newcap calculation overflowed.
    		if newcap <= 0 {
    			newcap = cap
    		}
    	}
    }

    从上面的代码可以看出以下内容:

    • 首先判断,如果新申请容量(cap)大于2倍的旧容量(old.cap),最终容量(newcap)就是新申请的容量(cap)。
    • 否则判断,如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap),
    • 否则判断,如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
    • 如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)。

    需要注意的是,切片扩容还会根据切片中元素的类型不同而做不同的处理,比如intstring类型的处理方式就不一样。

    示例

    package main
    
    import "fmt"
    
    type slice struct {
        ptr *[100]int
        len int
        cap int
    }
    
    func make1(s slice, cap int) slice {
        s.ptr = new([100]int)
        s.cap = cap
        s.len = 0
        return s
    }
    
    func testSlice() {
        var slice []int
        var arr [5]int = [...]int{1, 2, 3, 4, 5}
    
        slice = arr[:]
        fmt.Println(slice)
        fmt.Println(arr[2:4]) // [3,4]
        fmt.Println(arr[2:])  // [3,4,5]
        fmt.Println(arr[0:1]) // [1]
        fmt.Println(arr[:len(arr)-1])
    }
    
    func modify(s slice) {
        s.ptr[1] = 1000
    }
    
    func testSlice2() {
        var s1 slice
        s1 = make1(s1, 10)
    
        s1.ptr[0] = 100
        modify(s1)
    
        fmt.Println(s1.ptr)
    }
    
    func modify1(a []int) {
        a[1] = 1000
    }
    
    func testSlice3() {
        var b []int = []int{1, 2, 3, 4}
        modify1(b)
        fmt.Println(b)
    }
    
    func testSlcie4() {
        var a = [10]int{1, 2, 3, 4}
    
        b := a[1:5]
        fmt.Printf("%p
    ", b)     // 0xc000014238
        fmt.Printf("%p
    ", &a[1]) // 0xc000014238
    }
    
    func main() {
        // testSlice()
        testSlice2()
        testSlice3()
        testSlcie4()
    }
    切片的用法示例一
    package main
    
    import "fmt"
    
    func testSlice() {
        var a [5]int = [...]int{1, 2, 3, 4, 5}
        s := a[1:]
        fmt.Println("a:", a)
        s[1] = 100
        fmt.Printf("s=%p a[1]=%p
    ", s, &a[1])
        fmt.Println("before a:", a)
    
        s = append(s, 10)
        s = append(s, 10)
        s = append(s, 10)
        s = append(s, 10)
        s = append(s, 10)
    
        s[1] = 1000
        fmt.Println("after a:", a)
        fmt.Println(s)
        fmt.Printf("s=%p a[1]=%p
    ", s, &a[1])
    }
    
    func testCopy() {
        var a []int = []int{1, 2, 3, 4, 5}
        b := make([]int, 10)
    
        copy(b, a)
    
        fmt.Println(b)
    }
    
    func testString() {
        s := "hello world"
        s1 := s[0:5]
        s2 := s[6:]
    
        fmt.Println(s1)
        fmt.Println(s2)
    }
    
    func testModifyString() {
        s := "我hello world"
        s1 := []rune(s)
    
        s1[0] = 200
        s1[1] = 128
        s1[2] = 256
        str := string(s1)
        fmt.Println(str)
    }
    
    func main() {
        // testSlice()
        testCopy()
        testString()
        testModifyString()
    }
    切片的用法示例二
    package main
    
    import (
        "fmt"
        "sort"
    )
    
    func testIntSort() {
        var a = [...]int{1, 8, 43, 2, 456}
        sort.Ints(a[:])
        fmt.Println(a)
    }
    
    func testStrings() {
        var a = [...]string{"abc", "efg", "b", "A", "eeee"}
        sort.Strings(a[:])
    
        fmt.Println(a)
    }
    
    func testFloat() {
        var a = [...]float64{2.3, 0.8, 28.2, 392342.2, 0.6}
        sort.Float64s(a[:])
        fmt.Println(a)
    }
    
    func testIntSearch() {
        var a = [...]int{1, 8, 43, 2, 456}
        index := sort.SearchInts(a[:], 2)
        fmt.Println(index)
    }
    
    func main() {
        testIntSort()
        testStrings()
        testFloat()
        testIntSearch()
    }
    切片的用法示例三

    二、map数据结构

    1.map简介

    key-value的数据结构,又叫字典或关联数组
    a.声明

    var map1 map[keytype]valuetype
    var a map[string]string
    var a map[string]int
    var a map[int]string
    var a map[string]map[string]string

    声明是不会分配内存的,初始化需要make

    2. map相关操作

    var a map[string]string = map[string]string{“hello”: “world”}
    a = make(map[string]string, 10)
    a[“hello”] = “world”	// 插入和更新
    Val, ok := a[“hello”]	//查找
    for k, v := range a {	//遍历
    fmt.Println(k,v)
    }
    delete(a, “hello”)	// 删除
    len(a)	// 长度

    3. map是引用类型

    func modify(a map[string]int) {
    a[“one”] = 134
    }

    4. slice of map

    Items := make([]map[int][int], 5)
    For I := 0; I < 5; i++ {
    items[i] = make(map[int][int])
    }

    5. map排序

    a. 先获取所有key,把key进行排序
    b. 按照排序好的key,进行遍历

    6. Map反转

    • a. 初始化另外一个map,把key、value互换即可

     示例

    package main
    
    import "fmt"
    
    func trans(a map[string]map[string]string) {
        for k, v := range a {
            fmt.Println(k)
            for k1, v1 := range v {
                fmt.Println("	", k1, v1)
            }
        }
    }
    
    func testMap() {
        var a map[string]string = map[string]string{
            "key": "value",
        }
        // a := make(map[string]string, 10)
        a["abc"] = "efg"
        a["abc1"] = "wew"
        fmt.Println(a)
    }
    
    func testMap2() {
        a := make(map[string]map[string]string, 100)
        a["key1"] = make(map[string]string)
        a["key1"]["key2"] = "val2"
        a["key1"]["key3"] = "val3"
        a["key1"]["key4"] = "val4"
        a["key1"]["key5"] = "val5"
        a["key1"]["key6"] = "val6"
        fmt.Println(a)
    
    }
    
    func modify(a map[string]map[string]string) {
        _, ok := a["zhangsan"]
        if !ok {
            a["zhangsan"] = make(map[string]string)
        }
        a["zhangsan"]["pwd"] = "123456"
        a["zhangsan"]["nickname"] = "superman"
        return
    }
    
    func testMap3() {
        a := make(map[string]map[string]string, 100)
        modify(a)
        fmt.Println(a)
    }
    
    func testMap4() {
        a := make(map[string]map[string]string, 100)
        a["key1"] = make(map[string]string)
        a["key1"]["key2"] = "val2"
        a["key1"]["key3"] = "val3"
        a["key1"]["key4"] = "val4"
        a["key1"]["key5"] = "val5"
        a["key2"] = make(map[string]string)
        a["key2"]["key22"] = "val22"
        a["key2"]["key23"] = "val23"
        trans(a)
        delete(a, "key1")
        fmt.Println()
        trans(a)
    }
    
    func testMap5() {
        var a []map[int]int
        a = make([]map[int]int, 5)
    
        if a[0] == nil {
            a[0] = make(map[int]int)
        }
        a[0][10] = 10
        fmt.Println(a)
    }
    
    func main() {
        testMap()
        testMap2()
        testMap3()
        testMap4()
        testMap5()
    }
    map示例
    package main
    
    import (
        "fmt"
        "sort"
    )
    
    func testMapSort() {
        var a map[int]int
        a = make(map[int]int, 5)
    
        a[8] = 10
        a[3] = 10
        a[2] = 10
        a[1] = 10
        a[18] = 10
    
        var keys []int
        for k, _ := range a {
            keys = append(keys, k)
            // fmt.Println(k, v)
        }
        sort.Ints(keys)
        for _, v := range keys {
            fmt.Println(v, a[v])
        }
    }
    
    func testMapSort2() {
        var a map[string]int
        var b map[int]string
    
        a = make(map[string]int, 5)
        b = make(map[int]string, 5)
        a["8"] = 10
        a["3"] = 11
        a["2"] = 12
        a["1"] = 13
        a["18"] = 14
    
        for k, v := range a {
            b[v] = k
        }
        fmt.Println(b)
    }
    
    func main() {
        testMapSort()
        testMapSort2()
    }
    map示例2

    补充:golang实现集合(set)

    package set
     
    import (
        "bytes"
        "fmt"
        "sync"
    )
     
    type Set struct {
        m map[interface{}]bool
        sync.RWMutex
    }
     
    func New() *Set {
        return &Set{m: make(map[interface{}]bool)}
    }
     
    func (self *Set) Add(e interface{}) bool {
        self.Lock()
        defer self.Unlock()
        if self.m[e] {
            return false
        }
        self.m[e] = true
        return true
    }
     
    func (self *Set) Remove(e interface{}) bool {
        self.Lock()
        defer self.Unlock()
        delete(self.m, e)
        return true
    }
     
    func (self *Set) Clear() bool {
        self.Lock()
        defer self.Unlock()
        self.m = make(map[interface{}]bool)
        return true
    }
     
    func (self *Set) Contains(e interface{}) bool {
        self.Lock()
        defer self.Unlock()
        //return self.m[e]
        _, ok := self.m[e]
        return ok
    }
     
    func (self *Set) IsEmpty() bool {
        return self.Len() == 0
    }
     
    func (self *Set) Len() int {
        self.Lock()
        defer self.Unlock()
        return len(self.m)
    }
     
    func (self *Set) Same(other *Set) bool {
        if other == nil {
            return false
        }
     
        if self.Len() != other.Len() {
            return false
        }
     
        for k, _ := range other.m {
            if !self.Contains(k) {
                return false
            }
        }
        return true
    }
     
    func (self *Set) Elements() interface{} {
        self.Lock()
        defer self.Unlock()
        // for k := range self.m{
        //    snapshot = snapshot(snapshot, k)
        // }
        initialLen := self.Len()
        actualLen := 0
        snapshot := make([]interface{}, initialLen)
        for k := range self.m {
            if actualLen < initialLen {
                snapshot[actualLen] = k
            } else {
                snapshot = append(snapshot, k)
            }
            actualLen++
        }
        if actualLen < initialLen {
            snapshot = snapshot[:actualLen]
        }
        return snapshot
    }
     
    func (self *Set) String() string {
        self.Lock()
        defer self.Unlock()
        var buf bytes.Buffer
        buf.WriteString("Set{")
        flag := true
        for k := range self.m {
            if flag {
                flag = false
            } else {
                buf.WriteString(" ")
            }
            buf.WriteString(fmt.Sprintf("%v", k))
        }
        buf.WriteString("}")
     
        return buf.String()
    }
     
    func (self *Set) IsSuperSet(other *Set) bool {
        self.Lock()
        defer self.Unlock()
        if other == nil {
            return false
        }
        selfLen := self.Len()
        otherLen := other.Len()
        if otherLen == 0 || selfLen == otherLen {
            return false
        }
        if selfLen > 0 && otherLen == 0 {
            return true
        }
        for v := range other.m {
            if !self.Contains(v) {
                return false
            }
        }
        return true
    }
     
    //属于A或属于B的元素
    func (self *Set) Union(other *Set) *Set {
        self.Lock()
        defer self.Unlock()
        // if other == nil || other.Len() == 0{
        //    return self
        // }
        //
        // for v := range other.m{
        //    self.Add(v)
        // }
        // return self
        //不能改变集合A的范围
        union := New()
        for v := range self.m {
            union.Add(v)
        }
        for v := range other.m {
            union.Add(v)
        }
        return union
    }
     
    //属于A且属于B的元素
    func (self *Set) Intersect(other *Set) *Set {
        self.Lock()
        defer self.Unlock()
        if other == nil || other.Len() == 0 {
            return New()
        }
        intsSet := New()
        for v, _ := range other.m {
            if self.Contains(v) {
                intsSet.Add(v)
            }
        }
        return intsSet
    }
     
    //属于A且不属于B的元素
    func (self *Set) Difference(other *Set) *Set {
        self.Lock()
        defer self.Unlock()
        diffSet := New()
        if other == nil || other.Len() == 0 {
            diffSet.Union(self)
        } else {
            for v := range self.m {
                if !other.Contains(v) {
                    diffSet.Add(v)
                }
            }
        }
     
        return diffSet
    }
     
    //集合A与集合B中所有不属于A∩B的元素的集合
    func (self *Set) SymmetricDifference(other *Set) *Set {
        self.Lock()
        defer self.Unlock()
        //此时A∩B=∅,A中所有元素均不属于空集
        // if other == nil || other.Len() == 0{
        //    return self
        // }
        // ints := self.Intersect(other)
        // //此时A∩B=∅,A为空或B为空,B为空前面已经判断,此时B不能为空,即A为空
        // if ints == nil || ints.Len() == 0 {
        //    return other
        // }
        //
        // unionSet := self.Union(other)
        // result := New()
        // for v := range unionSet.m{
        //    if !ints.Contains(v){
        //       result.Add(v)
        //    }
        // }
        ints := self.Difference(other)
        union := self.Union(other)
        return union.Difference(ints)
    }
    package set
    package main
     
    import (
        "fmt"
        "go_dev/go_set/set"
    )
     
    func main() {
        setTest()
    }
     
    func setTest() {
        set1 := set.New()
        set1.Add(1)
        set1.Add("e2")
        set1.Add(3)
        set1.Add("e4")
        fmt.Println("set1:", set1)
        fmt.Printf("set1 Elements:%v
    ", set1.Elements())
     
        set2 := set.New()
        set2.Add(3)
        set2.Add("e2")
        set2.Add(5)
        set2.Add("e6")
     
        fmt.Println("set2:", set2)
        fmt.Printf("set1 union set2:%v
    ", set1.Union(set2))
        fmt.Printf("set1 intersect set2:%v
    ", set1.Intersect(set2))
        fmt.Println(set1,set2)
        fmt.Printf("set1 difference set2:%v
    ", set1.Difference(set2))
        fmt.Printf("set1 SymmetricDifference set2:%v
    ", set1.SymmetricDifference(set2))
        set1.Clear()
        fmt.Println(set1)
    }
    main.go

    三、包

    1. golang中的包

    • a. golang目前有150个标准的包,覆盖了几乎所有的基础库

    • b. golang.org有所有包的文档,没事都翻翻

    2. 线程同步

    a. import(“sync”)
    b. 互斥锁, var mu sync.Mutex
    c. 读写锁, var mu sync.RWMutex
    package main
    
    import (
        "fmt"
        "math/rand"
        "sync"
        "sync/atomic"
        "time"
    )
    
    var rwLock *sync.RWMutex
    
    func testLock() {
    
        var a map[int]int
        a = make(map[int]int, 5)
    
        a[8] = 10
        a[3] = 10
        a[2] = 10
        a[1] = 10
        a[18] = 10
    
        for i := 0; i < 2; i++ {
            go func(b map[int]int) {
                rwLock.RLock()
                b[8] = rand.Intn(100)
                rwLock.Unlock()
            }(a)
        }
    
        rwLock.RLock()
        fmt.Println(a)
        rwLock.Unlock()
    }
    
    func testRWLock() {
        // var rwLock myLocker = new(sync.RWMutex)
        // var rwLock sync.RWMutex
        // var rwLock sync.Mutex
        var a map[int]int
        a = make(map[int]int, 5)
    
        var count int32
    
        a[8] = 10
        a[3] = 10
        a[2] = 10
        a[1] = 10
        a[18] = 10
    
        for i := 0; i < 2; i++ {
            go func(b map[int]int) {
                rwLock.Lock()
                // lock.Lock()
                b[8] = rand.Intn(100)
                time.Sleep(time.Millisecond)
                rwLock.Unlock()
                // lock.Unlock()
            }(a)
        }
    
        for i := 0; i < 100; i++ {
            go func(b map[int]int) {
                for {
                    rwLock.Lock()
                    time.Sleep(time.Millisecond)
                    // fmt.Println(a)
                    rwLock.Unlock()
                    atomic.AddInt32(&count, 1)
                }
            }(a)
        }
    
        time.Sleep(time.Second * 3)
        fmt.Println(atomic.LoadInt32(&count))
    }
    
    func main() {
        rwLock = new(sync.RWMutex)
        // testLock()
        testRWLock()
    }
    线程同步锁示例

    3. go get安装第三方包

    go get github.com/go-sql-driver/mysql 

    本节作业

    • 1. 冒泡排序

    • 2. 选择排序

    • 3. 插入排序

    • 4.快速排序

    参考

    package main
    
    import "fmt"
    
    // 冒泡排序:本质上是交换排序的一种
    func bsort(a []int) {
        for i := 0; i < len(a); i++ {
            for j := 1; j < len(a)-i; j++ {
                if a[j] < a[j-1] {
                    a[j], a[j-1] = a[j-1], a[j]
                }
            }
        }
    }
    
    func main() {
        b := [...]int{8, 7, 4, 5, 3, 2, 1}
        bsort(b[:])
        fmt.Println(b)
    }
    冒泡排序
    package main
    
    import "fmt"
    
    // 选择排序
    func ssort(a []int) {
        for i := 0; i < len(a); i++ {
            var min int = i
            for j := i + 1; j < len(a); j++ {
                if a[min] > a[j] {
                    min = j
                }
            }
            if min != i {
                a[i], a[min] = a[min], a[i]
            }
        }
    }
    
    func main() {
        b := [...]int{8, 7, 4, 5, 3, 2, 1}
        ssort(b[:])
        fmt.Println(b)
    }
    选择排序
    package main
    
    import "fmt"
    
    // 插入排序, 每次将一个数插入到有序序列当中合适的位置
    func isort(a []int) {
        for i := 1; i < len(a); i++ {
            for j := i; j > 0; j-- {
                if a[j] > a[j-1] {
                    break
                }
                a[j], a[j-1] = a[j-1], a[j]
            }
        }
    }
    
    func main() {
        b := [...]int{8, 7, 4, 5, 3, 2, 1}
        isort(b[:])
        fmt.Println(b)
    }
    插入排序
    package main
    
    import "fmt"
    
    // 快速排序, 一次排序确定一个元素的位置, 使左边的元素都比它小,右边的元素都比它大
    func qsort(a []int, left, right int) {
        if left >= right {
            return
        }
        val := a[left]
        // 确定val所在的位置
        k := left
        for i := left + 1; i <= right; i++ {
            if a[i] < val {
                a[k] = a[i]
                a[i] = a[k+1]
                k++
            }
        }
        a[k] = val
        qsort(a, left, k-1)
        qsort(a, k+1, right)
    }
    
    func main() {
        b := [...]int{8, 7, 4, 5, 3, 2, 1}
        qsort(b[:], 0, len(b)-1)
        fmt.Println(b)
    }
    快速排序
  • 相关阅读:
    BZOJ1316——树上的询问(点分治)
    BZOJ2152——聪聪可可(点分治)
    POJ1741(点分治)
    POJ2104——K-th Number (主席树模板)
    USACO Training Section 5.1 Fencing the Cows 圈奶牛(凸包)
    POJ1269(直线之间的关系)
    NOIP2016——换教室(floyd+期望dp)
    POJ2187(旋转卡壳)
    POJ3348——Cows(求凸包)
    ZOJ1081(射线法判断点是否在多边形内部)
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/10659829.html
Copyright © 2011-2022 走看看