Go 语言实现常见排序算法(上)

简介: 在每次迭代过程中算法随机地从输入序列中移除一个元素,并将改元素插入待排序序列的正确位置

计数排序

package sort
func countingSort(arr []int, bias int) (retArr []int) {
  countingArr := make([]int, bias+1, bias+1)
  retArr = make([]int, len(arr), cap(arr))
  for _, v := range arr {
    countingArr[v]++
  }
  for i := 1; i < len(countingArr); i++ {
    countingArr[i] += countingArr[i-1]
  }
  for i := len(arr) - 1; i >= 0; i-- {
    retArr[countingArr[arr[i]]-1] = arr[i]
    countingArr[arr[i]]--
  }
  return
}

插入排序

插入排序,英文名(insertion sort)是一种简单且有效的比较排序算法。


思想: 在每次迭代过程中算法随机地从输入序列中移除一个元素,并将改元素插入待排序序列的正确位置。重复该过程,直到所有输入元素都被选择一次,排序结束。


类比:抓牌

package sort
func insertionSort(unsorted []int) {
    length = len(unsorted)
    for i := 0; i < length; i++ {
        var insertElement = unsorted[i]
        var insertPosition = i
        for j := insertPosition - 1; j >= 0; j-- {
            if insertElement < unsorted[j] {
                unsorted[j+1] = unsorted[j]
                insertPosition--
            }
        }
        unsorted[insertPosition] = insertElement
    }
}


冒泡排序

冒泡排序是一种最简单的交换排序算法。


什么是交换?交换就是两两进行比较,如果不满足次序就可以交换位置。比如,我们想要从小到大排序,通过两个位置上的值两两比较,如果逆序就交换,使关键字大的记录像泡泡一样冒出来放在末尾。重复执行若干次冒泡排序,最终得到有序序列。


类比: 值较小的元素如同”气泡“一样逐渐漂浮到序列的顶端。

package sort
func bubbleSort(nums []int) {
    length = len(nums)
    lastSwap := length - 1
    lastSwapTemp := length - 1
    for j := 0; j < length; j++ {
        lastSwap = lastSwapTemp
        for i := 0; i < lastSwap; i++ {
            if nums[i] > nums[i+1] {
                nums[i], nums[i+1] = nums[i+1], nums[i]
                lastSwapTemp = i
            }
        }
        if lastSwap == lastSwapTemp {
            break
        }
    }
}

选择排序

选择排序(selection sort)是一种原地(in-place)排序算法,适用于数据量较少的情况。由于选择操作是基于键值的且交换操作只在需要时才执行,所以选择排序长用于数值较大和键值较小的文件。

package sort
func selectionSort(nums []int) {
  length = len(nums)
  var minIdx int // 被选择的最小的值的位置
  for i := 0; i < length-1; i++ {
    minIdx = i
    // 每次循环的第一个元素为最小值保存
    var minValue = nums[minIdx]
    for j := i; j < length-1; j++ {
      if minValue > nums[j+1] {
        minValue = nums[j+1]
        minIdx = j + 1
      }
    }
    // 如果最小值的位置改变,将当前的最小值位置保存
    if i != minIdx {
      var temp = nums[i]
      nums[i] = nums[minIdx]
      nums[minIdx] = temp
    }
  }
}


堆排序

堆排序是一种树形选择排序算法。堆排序的过程:


  1. 构建初始堆
  2. 在输出堆的顶层元素后,从上到下进行调整,将顶层元素与其左右子树的根节点进行比较,并将最小的元素交换到堆的顶部;然后不断调整直到叶子节点得到新的堆。
package sort
import (
  "github.com/shady831213/algorithms/heap"
)
func heapSort(arr []int) {
  h := heap.NewHeapIntArray(arr)
  for i := h.Len() - 1; i > 0; i-- {
    h.Pop()
  }
}
/*not generic heap*/
type intArrayForHeapSort []int
func (h *intArrayForHeapSort) parent(i int) int {
  return i >> 1
}
func (h *intArrayForHeapSort) left(i int) int {
  return (i << 1) + 1
}
func (h *intArrayForHeapSort) right(i int) int {
  return (i << 1) + 2
}
func (h *intArrayForHeapSort) maxHeaplify(i int) {
  largest, largestIdx := (*h)[i], i
  if (*h).left(i) < len((*h)) && (*h)[(*h).left(i)] > largest {
    largest, largestIdx = (*h)[(*h).left(i)], (*h).left(i)
  }
  if h.right(i) < len((*h)) && (*h)[h.right(i)] > largest {
    _, largestIdx = (*h)[h.right(i)], h.right(i)
  }
  if i != largestIdx {
    (*h)[largestIdx], (*h)[i] = (*h)[i], (*h)[largestIdx]
    h.maxHeaplify(largestIdx)
  }
}
func (h *intArrayForHeapSort) buildHeap() {
  for i := (len((*h)) >> 1) - 1; i >= 0; i-- {
    h.maxHeaplify(i)
  }
}
func heapSort2(arr []int) {
  h := intArrayForHeapSort(arr)
  h.buildHeap()
  for i := len(h) - 1; i > 0; i-- {
    h[0], h[i] = h[i], h[0]
    h = h[:i]
    h.maxHeaplify(0)
  }
}
相关文章
|
1天前
|
安全 Java Go
探索Go语言在高并发环境中的优势
在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
|
5天前
|
运维 Kubernetes Go
"解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
24 1
|
6天前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
13 1
|
6天前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
7天前
|
JSON 缓存 监控
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
Viper 是一个强大的 Go 语言配置管理库,适用于各类应用,包括 Twelve-Factor Apps。相比仅支持 `.ini` 格式的 `go-ini`,Viper 支持更多配置格式如 JSON、TOML、YAML
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
|
1天前
|
监控 NoSQL Go
Go语言中高效使用Redis的Pipeline
Redis 是构建高性能应用时常用的内存数据库,通过其 Pipeline 和 Watch 机制可批量执行命令并确保数据安全性。Pipeline 类似于超市购物一次性结账,减少网络交互时间,提升效率。Go 语言示例展示了如何使用 Pipeline 和 Pipelined 方法简化代码,并通过 TxPipeline 保证操作原子性。Watch 机制则通过监控键变化实现乐观锁,防止并发问题导致的数据不一致。这些机制简化了开发流程,提高了应用程序的性能和可靠性。
5 0
|
3天前
|
NoSQL Go Redis
Go语言中如何扫描Redis中大量的key
在Redis中,遍历大量键时直接使用`KEYS`命令会导致性能瓶颈,因为它会一次性返回所有匹配的键,可能阻塞Redis并影响服务稳定性。为解决此问题,Redis提供了`SCAN`命令来分批迭代键,避免一次性加载过多数据。本文通过两个Go语言示例演示如何使用`SCAN`命令:第一个示例展示了基本的手动迭代方式;第二个示例则利用`Iterator`简化迭代过程。这两种方法均有效地避免了`KEYS`命令的性能问题,并提高了遍历Redis键的效率。
11 0
|
4天前
|
监控 Serverless Go
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
|
5天前
|
关系型数据库 MySQL 数据库连接
Go语言中使用sqlx来操作事务
在应用中,数据库事务保证操作的ACID特性至关重要。`github.com/jmoiron/sqlx`简化了数据库操作。首先安装SQLX和MySQL驱动:`go get github.com/jmoiron/sqlx`和`go get github.com/go-sql-driver/mysql`。导入所需的包后,创建数据库连接并使用`Beginx()`方法开始事务。通过`tx.Commit()`提交或`tx.Rollback()`回滚事务以确保数据一致性和完整性。
8 0
|
人工智能 算法 Go
使用golang学习算法(1)-排序
前言 终于感觉到算法的重要了。于是打算继续学习下。 其实算法跟语言没有啥关系,用啥语言都可以实现关键是思路,最近正好在学习golang。打算把算法的编写使用golang完成。 没有使用IDE,使用的是sublime2+ golang的插件,然后使用命令行进行编译。 开发效率也不低,也支持语言的自动补齐。 搭建环境【http://blog.csdn.net/freewebsys/a
1060 0