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),
)
}

最新文章

  1. android压力测试命令monkey详解
  2. 教你把UltraEdit如何注册激活教程及UltraEdit 22.0.0.48 官方中文版下载
  3. fanghuangscannerV3 字典生成器
  4. jquery easyui datagraid 对象显示的方法与datagraid、分页、复选框多选的数据显示
  5. Xml文件保存值不能及时更新
  6. Ural 1046 Geometrical Dreams(解方程+计算几何)
  7. Android Timer的使用
  8. 使用FileSystemWatcher捕获系统文件状态
  9. 基于visual Studio2013解决算法导论之004随机排列数组
  10. STL该反应堆运行
  11. rpm包管理
  12. lucene索引库的增删改查操作
  13. android调试工具adb命令大全
  14. j旧学习
  15. MySQL、MongoDB、Redis 数据库之间的区别
  16. 基于spring的PropertySource类实现配置的动态替换
  17. Linux运维工程师必学必备的8项IT技能
  18. MyEclipse配置Hibernate具体步骤
  19. 域hash值破解的总结经验
  20. 对SSL一个疑问的新理解

热门文章

  1. IsNotEmpty和isNotBlank的区别
  2. Lua文件夹及文件操作
  3. vue 3.0 总线程bus引入(mitt)
  4. 快速确定execl 列数
  5. 浅谈AD域
  6. @Configuration 配置类打断点后,一启动项目读取到该配置类的话就会进断点
  7. 转载-GNSS缩写
  8. geoserver的自动化部署
  9. C# 数据结构之嵌套加法、嵌套乘法
  10. android控制台应用binder通讯