golang 各种排序大比拼实例

论坛 期权论坛 脚本     
niminba   2021-5-23 03:01   839   0

1、准备工作

准备数据:

生成随机数并写入文件,之后在把数据读取出来

//新生成整数随机数,并存储在txt文件中,
func NewIntRandm(fileName string, number, maxrandm int) {
 filename := fileName
 file, err := os.Create(filename)
 if err != nil {
  return
 }
 r := rand.New(rand.NewSource(time.Now().UnixNano()))
 rans := make([]string, 0, number)
 for i := 0; i < number; i++ {
  rans = append(rans, strconv.Itoa(r.Intn(maxrandm)))
 }
 file.WriteString(strings.Join(rans, " "))
 defer file.Close()
}
//把一串数组存入文件总
func SavaRandmInt(fileName string, data []int) {
 if fileName == " " || len(data) == 0 {
  return
 }
 var file *os.File
 var openerr error
 file, openerr = os.Open(fileName)
 if openerr != nil {
  var newerr error
  file, newerr = os.Create(fileName)
  if newerr != nil {
   return
  }
 }
 rans := make([]string, 0, len(data))
 for _, v := range data {
  rans = append(rans, strconv.Itoa(v))
 }
 file.WriteString(strings.Join(rans, " "))
 defer file.Close()
}

准备计时的程序:

package util
import "time"
type Stopwatch struct {
 start time.Time
 stop time.Time
}
func (s *Stopwatch) Start() {
 s.start = time.Now()
}
func (s *Stopwatch) Stop() {
 s.stop = time.Now()
}
//纳秒
func (s Stopwatch) RuntimeNs() int {
 return s.stop.Nanosecond() - s.start.Nanosecond()
}
//微妙
func (s Stopwatch) RuntimeUs() float64 {
 return (float64)(s.stop.Nanosecond()-s.start.Nanosecond()) / 1000.00
}
//毫秒
func (s Stopwatch) RuntimeMs() float64 {
 return (float64)(s.stop.Nanosecond()-s.start.Nanosecond()) / 1000000.00
}
//秒
func (s Stopwatch) RuntimeS() float64 {
 return (float64)(s.stop.Nanosecond()-s.start.Nanosecond()) / 10000000000.00
}

2、开始写排序

我模仿golang中的sort源码包中的写法,暴露了一个接口,把排序的实现都写在内部

package sort
// package main
type Interface interface {
 //获取数据的长度
 Len() int
 //判读索引为i和索引为j的值的大小,在实现的时候如果判断i>j 返回true,则为升序,反之为降序
 Less(i, j int) bool
 //交换索引i,j的值
 Swap(i, j int)
}
//冒泡排序
func BubbleSort(data Interface) {
 n := data.Len()
 for index := 0; index < n; index++ {
  for j := index + 1; j < n; j++ {
   if data.Less(index, j) {
    data.Swap(index, j)
   }
  }
 }
}
//此方法比上面的冒泡算法快,因为我找最小元素是指记住下标,并没有每一次都做元素交换
func SelectSort(data Interface) {
 n := data.Len()
 var min int
 for index := 0; index < n; index++ {
  min = index
  for j := index + 1; j < n; j++ {
   if data.Less(min, j) {
    min = j
   }
  }
  data.Swap(index, min)
 }
}
//插入排序
func InsertSrot(data Interface) {
 count := data.Len()
 for index := 1; index < count; index++ {
  for j := index; j > 0 && data.Less(j, j-1); j-- { //j>0 做一个边界守护,不让下标小于0
   data.Swap(j, j-1)
  }
 }
}
//希尔排序
func ShellSort(data Interface) {
 N := data.Len()
 h := 1
 for h < N/3 {
  h = 3*h + 1
 }
 for h > 0 {
  for index := h; index < N; index++ {
   for j := index; j >= h && data.Less(j, j-h); j -= h { //j>0 做一个边界守护,不让下标小于0
    data.Swap(j, j-h)
   }
  }
  h = h / 3
 }
}
//快速排序
func QuickSort(data Interface) {
 n := data.Len()
 low, row := 0, n-1
 quickSort(data, low, row)
}
func quickSort(data Interface, low, row int) {
 if low < row {
  i, j, x, last := low, row, low, 0 //0就是使用第一个作为基准值,last这个变量时为了基准最后一次交换变量时出现在那次
  for i < j {
   for i < j && data.Less(x, j) { //比x小的放在前面出现的坑中
    j--
   }
   if i < j {
    data.Swap(i, j)
    i++
    x = j
    last = 1
   }
   for i < j && data.Less(i, x) { //比x大的放在后面出现的坑中
    i++
   }
   if i < j {
    data.Swap(i, j)
    j--
    x = i
    last = -1
   }
  }
  if last == 1 {
   data.Swap(j, x)
  } else if last == -1 {
   data.Swap(i, x)
  }
  quickSort(data, low, i-1)
  quickSort(data, i+1, row)
 }
}
//通过控制Less方法来控制升序降序
func HeapSort(data Interface) {
 makeHeap(data)
 n := data.Len()
 for i := n - 1; i >= 1; i-- {
  data.Swap(0, i)
  heapFixdown(data, 0, i)
 }
}
func makeHeap(data Interface) {
 n := data.Len()
 for i := (n - 1) >> 1; i >= 0; i-- {
  heapFixdown(data, i, n)
 }
}
func heapFixdown(data Interface, r, n int) {
 root := r //跟结点
 for {
  leftChildIndex := root<<1 + 1
  if leftChildIndex >= n {
   break
  }
  if leftChildIndex+1 < n && data.Less(leftChildIndex+1, leftChildIndex) {
   leftChildIndex++
  }
  if data.Less(root, leftChildIndex) {
   return
  }
  data.Swap(leftChildIndex, root)
  root = leftChildIndex
 }
}

3、开始使用

//先实现这个排序接口
type InSort []int
func (is InSort) Len() int {
 return len(is)
}//降序
func (is InSort) Less(i, j int) bool {
 return is[H"&3^^Ч_7^^J3j*&3^^чk^*Bfvч^^'fRK+gr?3jB;vf"Z>+"bv{h4(4)ш	Фш*R4(7^^jKфРr&3jJ37^^jшФф4(4(7^>&1n:4(ш4(ф>Yjj_7^^jф4(чb;">G^^::rч^^(йЁЁ4(йфй_&3*j^^(ёQшаV4(zsr'&3^^gJ16b>&3k^*шФ(шt4(ш(шt4(ш鱅t4(ёQша4(й4(й4(й4(й(шR4(r>GzRKb{j6?,4(ш4(ф9Ё4(ш	4(4(чb;7^k^*:b{vr4(ш4(шф4(ш4(шфvrч^^KB;>&3rjk^*(4(4(Q>+"j*vObB*k^*^k"oR6?/B&r'j6?/B4(B;G7bj{:4(4(鱥MM)MФ"ok^*4(й_k^*j&3^^
йI&3ZT4(шФ*rk^*&36?/'&04(шMvr'^*6?/k~RH4)4(jB;b>G:J1Qj#3*k^*B6?/{r{fRjB3k^*B6?/'B4(皾Sr"G~O.Rjz3RB36?/Bgr/vQr'24({fbr'2jbvr3"Ck^*RK	Qbb{76?/3"Ck^*j&37ib{J3vrj_'2gZ4(b{6?/3"Ck^*SB!^^^>+&3ZW3>j*^>+r?"Cv*rcrn{r^^Ч4(&Q3"Ck^*4(33ro>rokkR2r'Rg"[rfG3jrZ3roBwVg
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP