blockchain-go語言常用算法

冒泡排序

package main

import "fmt"
//定義一個排序的接口
type SortInterface interface {
  sort();
}
//定義額排序的結構體
type Sortor struct {
  name string
}

func main()  {
  arry :=[]int{12,15,6,8,4,3,18,3,7}
  learnsort := Sortor{name: "冒泡排序"}
  learnsort.sort(arry)
  fmt.Println(learnsort.name, arry)
}
//結構體實現接口,嵌套循環實現冒泡排序
func(sorter Sortor) sort(arry []int){
  done := true
  arrylength :=len(arry)
  for i:=0; i<arrylength && done; i++{
    done = false
    for j := 0; j < arrylength-i-1; j++ {
        done = true
        if arry[j] > arry[j+1] {
          t :=arry[j]
          arry[j] = arry[j+1]
          arry[j+1] = t
        }
    }
  }
}

快速排序

快速排序原理不多廢話,直接上代碼

package main

import "fmt"

func main(){
  arry :=[]int{12,15,6,8,4,3,18,3,7}
  sort2(arry, 0, len(arry)-1)
  fmt.Println(arry)
}
//快速排序代碼
func sort2(arry []int, low int, high int)  {
  startIndex :=low
  endIndex :=high
  key :=arry[0]
    for endIndex > startIndex {
      for endIndex > startIndex && arry[endIndex] >=   key {
          endIndex--
        }
          if arry[endIndex] <= key {
              temp := arry[endIndex]
              arry[endIndex] = arry[startIndex]
              arry[startIndex] = temp
          }


      for endIndex > startIndex && arry[startIndex] <= key {
          startIndex++
        }
          if arry[startIndex] >= key {
              temp := arry[startIndex]
              arry[startIndex] = arry[endIndex]
              arry[endIndex] = temp
          }


    }
    if startIndex > low{
        sort2(arry, low, startIndex-1)
    }
    if endIndex < high{
      sort2(arry, endIndex+1, high)
    }
}
//結果是[3 3 6 4 7 8 12 18 15]

簡單選擇排序

package main
import "fmt"

func main()  {
  arry :=[]int{12,15,6,8,4,3,18,3,7}
  sort3(arry)
  fmt.Println(arry)
}
//從前往後排,篩選出最小的往前移動
func sort3(arry1 []int)  {
  for i := 0; i < len(arry1)-1; i++{
      k := j;
      for j := k+1; j < len(arry1); j++{
        if arry1[j] < arry1[k]{
            k = j
        }
      }
      if i != k {
        temp := arry1[i]
        arry1[i] = arry1[k]
        arry1[k] = temp
      }
  }
}

堆排序

package main

import (
    "fmt"
)

//堆排序
//s[0]不用,實際元素從角標1開始
//父節點元素大於子節點元素
//左子節點角標爲2*k
//右子節點角標爲2*k+1
//父節點角標爲k/2
func HeapSort(s []int) {
    N := len(s) - 1 //s[0]不用,實際元素數量和最後一個元素的角標都爲N
    //構造堆
    //如果給兩個已構造好的堆添加一個共同父節點,
    //將新添加的節點作一次下沉將構造一個新堆,
    //由於葉子節點都可看作一個構造好的堆,所以
    //可以從最後一個非葉子節點開始下沉,直至
    //根節點,最後一個非葉子節點是最後一個葉子
    //節點的父節點,角標爲N/2
    for k := N / 2; k >= 1; k-- {
        sink(s, k, N)
    }
    //下沉排序
    for N > 1 {
        swap(s, 1, N) //將大的放在數組後面,升序排序
        N--
        sink(s, 1, N)
    }
}

//下沉(由上至下的堆有序化)
func sink(s []int, k, N int) {
    for {
        i := 2 * k
        if i > N { //保證該節點是非葉子節點
            break
        }
        if i < N && s[i+1] > s[i] { //選擇較大的子節點
            i++
        }
        if s[k] >= s[i] { //沒下沉到底就構造好堆了
            break
        }
        swap(s, k, i)
        k = i
    }
}

func swap(s []int, i int, j int) {
    s[i], s[j] = s[j], s[i]
}

func main()  {
  s := []int{-1,9, 0, 6, 5, 8, 2, 1, 7, 4, 3}
fmt.Println(s[1:])
HeapSort(s)
fmt.Println(s[1:])
}

直接插入排序

package main

import(
    "container/list"
    "fmt"
)

func main(){
  s := []int{9,0,6,5,8,2,1,7,4,3}
  fmt.Println(s)
  InsertionSort(s)
  fmt.Println(s)
}

func InsertionSort(s []int) {
    n := len(s)
    if n < 2 {
        return
    }

    for j := 1; j < n; j++ {
        for j := i; j > 0 && s[j] < s[j - 1]; j-- {
            swap(s, j, j - 1)
        }
    }
}
//交換
func swap(slice []int, j int, j int) {
    slice[j], slice[j] = slice[j], slice[j]
}


希爾排序

希爾排序的實質就是分組插入排序,該方法又稱縮小增量排序,因DL.Shell於1959年提出而得名。
該方法的基本思想是:先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。因爲直接插入排序在元素基本有序的情況下(接近最好情況),效率是很高的,因此希爾排序在時間效率上比前兩種方法有較大提高。
這裏寫圖片描述

package main

import(
    "fmt"
)

func main(){
  s := []int{9,0,6,5,8,2,1,7,4,3}
  fmt.Println(s)
  ShellSort(s,len(s))
  fmt.Println(s)
}

func ShellSort(arry []int, n int)  {
  for gap :=n/2; gap>0; gap/=2{
    for i :=gap; i<n; i++ {
      for j :=i-gap; j>=0 && arry[j] > arry[j+gap]; j -= gap {
        arry[j] , arry[j+gap] = arry[j+gap] , arry[j]
      }
    }
  }
}

合併排序

合併排序算法是用分治策略實現對N個元素進行排序的算法。其基本思想是:

將待排序元素分成大小大致相同 的兩個子集合,分別 對兩個子集合進行排序,最終將排好序的子集合合併成所要求的排好序的集合。

一句話概括就是將一段數據分成前後兩個的數組進行大小比較(分治到每一個小塊都是2個),然後再合併進行比較

package main

import "fmt"

func main()  {
  arr01:=[]int{4,3,20,7,10,9,11,2}

     fmt.Print("排序前")
     fmt.Println(arr01)

     mergeSort(arr01,0,len(arr01)-1)

     fmt.Print("排序後")
     fmt.Println(arr01)
}
func mergeSort(arr []int,low,high int){
    if low<high{
        mid:=(low+high)/2

        fmt.Println(arr)
        fmt.Println(low)
        fmt.Println(mid)
        fmt.Println(high)
        mergeSort(arr,low,mid)
        mergeSort(arr,mid+1,high)
        merge1(arr,low,mid,high)
    }
}
func merge1(arr []int,low,mid,high int){
    leftLen:=mid-low+1
    rightLen:=high-mid

    arrLeft:=make([]int,leftLen+1)


    for i:=0;i<leftLen;i++{
        arrLeft[i]=arr[low+i]
    }
    arrLeft[leftLen]=99999//哨兵牌

    arrRight:=make([]int,rightLen+1)
    for j:=0;j<rightLen;j++{
        arrRight[j]=arr[mid+j+1]
    }
    arrRight[rightLen]=99999//哨兵牌
    fmt.Println(arrRight)
    fmt.Println(arrLeft)
    i,j:=0,0
    for k:=low;k<=high;k++{
        if arrLeft[i]<=arrRight[j]{
            arr[k]=arrLeft[i]
            i++
        }else{
            arr[k]=arrRight[j]
            j++
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章