为了账号安全,请及时绑定邮箱和手机立即绑定

golang快速排序算法

标签:
Go


快速排序算法原理:

设置分水岭,把小于分水岭的数排到分水岭左侧,其余的排到右侧,递归的对分水岭两侧的元素做同样的处理

package qsort

func quickSort(values []int, left int, right int) {

  if left < right {

    // 设置分水岭

    temp := values[left]

    // 设置哨兵

    i, j := left, right

    for {

      // 从右向左找,找到第一个比分水岭小的数

      for values[j] >= temp && i < j {

        j--

      }

      // 从左向右找,找到第一个比分水岭大的数

      for values[i] <= temp && i < j {

        i++

      }

      // 如果哨兵相遇,则退出循环

      if i >= j {

        break

      }

      // 交换左右两侧的值

      values[i], values[j] = values[j], values[i]

    }

    // 将分水岭移到哨兵相遇点

    values[left] = values[i]

    values[i] = temp

    // 递归,左右两侧分别排序

    quickSort(values, left, i-1)

    quickSort(values, i+1, right)

  }

}

func QuickSort(values []int) {

  quickSort(values, 0, len(values)-1)

}

更简洁的版本:

package main

import "fmt"

func main() {

   numbers := []int{6, 2, 7, 7, 3, 8, 9}

   //fmt.Println(numbers)

   QuickSort(numbers)

   fmt.Println(numbers)

}

func QuickSort(values []int) {

   length := len(values)

   if length <= 1 {

      return

   }

   mid, i := values[0], 1    // 取第一个元素作为分水岭,i下标初始为1,即分水岭右侧的第一个元素的下标

   head, tail := 0, length-1 // 头尾的下标

   // 如果头和尾没有相遇,就会一直触发交换

   for head < tail {

      fmt.Println(values, head, tail, i)

      if values[i] > mid {

         // 如果分水岭右侧的元素大于分水岭,就将右侧的尾部元素和分水岭右侧元素交换

         values[i], values[tail] = values[tail], values[i]

         tail-- // 尾下标左移一位

      } else {

         // 如果分水岭右侧的元素小于等于分水岭,就将分水岭右移一位

         values[i], values[head] = values[head], values[i]

         head++ // 头下标右移一位

         i++    // i下标右移一位

      }

      fmt.Printf("----{head:%d,tail:%d,i:%d,mid:%d} values:%v\n", head, tail, i, mid, values)

   }

   // 分水岭左右的元素递归做同样处理

   QuickSort(values[:head])

   QuickSort(values[head+1:])

}

更容易理解的版本

package main

import "fmt"

func main() {

    arr := []int{5, 4, 3, 6, 7, 8}

    rs := qsort(arr)

    fmt.Println(rs)

    // [3 4 5 6 7 8]

}

// 快速排序

func qsort(arr []int) []int {

    if len(arr) < 2 {

        return arr

    } else {

        pivot := arr[0]

        var less []int

        var greater []int

        for _, value := range arr[1:] {

            if value <= pivot {

                less = append(less, value)

            } else {

                greater = append(greater, value)

            }

        }

        var result []int

        result = append(result, qsort(less)...)

        result = append(result, pivot)

        result = append(result, qsort(greater)...)

        return result

    }

}

©著作权归作者所有:来自51CTO博客作者ustb80的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消