每日一抄 Go语言封装qsort快速排序函数
2024-10-21 23:25:55
package qsort
/*
《GO语言高级编程》设计中案例,仅作为笔记进行收藏。
qsort快速排序函数是C语⾔的⾼阶函数,⽀持⽤于⾃定义排序⽐较函数,可以对任意类型的数组进⾏排序。
*/
//sort.go支持包
/*
#include <stdlib.h>
typedef int (*qsort_cmp_func_t)(const void* a, const void* b);
extern int _cgo_qsort_compare(void* a, void* b);
*/
import "C"
import (
"fmt"
"reflect"
"sync"
"unsafe"
)
var go_qsort_compare_info struct {
base unsafe.Pointer
elemnum int
elemsize int
less func(a, b int) bool
sync.Mutex
}
//export _cgo_qsort_compare
func _cgo_qsort_compare(a, b unsafe.Pointer) C.int {
var (
base = uintptr(go_qsort_compare_info.base)
elemsize = uintptr(go_qsort_compare_info.elemsize)
i = int((uintptr(a) - base) / elemsize)
j = int((uintptr(b) - base) / elemsize)
)
switch {
case go_qsort_compare_info.less(i, j):
//v[i] < v[j]
return -1
case go_qsort_compare_info.less(i, j):
//v[i] > v[j]
return +1
default:
return 0
}
}
func Slice(slice interface{}, less func(a, b int) bool) {
sv := reflect.ValueOf(slice)
if sv.Kind() != reflect.Slice {
panic(fmt.Sprintf("qsort called with non-slice value of type %T", slice))
}
if sv.Len() == 0 {
return
}
go_qsort_compare_info.Lock()
defer go_qsort_compare_info.Unlock()
defer func() {
go_qsort_compare_info.base = nil
go_qsort_compare_info.elemnum = 0
go_qsort_compare_info.elemsize = 0
go_qsort_compare_info.less = nil
}()
go_qsort_compare_info.base = unsafe.Pointer(sv.Index(0).Addr().Pointer())
go_qsort_compare_info.elemnum = sv.Len()
go_qsort_compare_info.elemsize = int(sv.Type().Elem().Size())
go_qsort_compare_info.less = less
C.qsort(
go_qsort_compare_info.base,
C.size_t(go_qsort_compare_info.elemnum),
C.size_t(go_qsort_compare_info.elemsize),
C.qsort_cmp_func_t(C._cgo_qsort_compare),
)
}
最新文章
- android压力测试命令monkey详解
- 教你把UltraEdit如何注册激活教程及UltraEdit 22.0.0.48 官方中文版下载
- fanghuangscannerV3 字典生成器
- jquery easyui datagraid 对象显示的方法与datagraid、分页、复选框多选的数据显示
- Xml文件保存值不能及时更新
- Ural 1046 Geometrical Dreams(解方程+计算几何)
- Android Timer的使用
- 使用FileSystemWatcher捕获系统文件状态
- 基于visual Studio2013解决算法导论之004随机排列数组
- STL该反应堆运行
- rpm包管理
- lucene索引库的增删改查操作
- android调试工具adb命令大全
- j旧学习
- MySQL、MongoDB、Redis 数据库之间的区别
- 基于spring的PropertySource类实现配置的动态替换
- Linux运维工程师必学必备的8项IT技能
- MyEclipse配置Hibernate具体步骤
- 域hash值破解的总结经验
- 对SSL一个疑问的新理解