FreeBASIC调用qsort排序

    FreeBASIC可以很方便的调用C函数库,试着调用了快速排序qsort函数,还是有些需要注意的地方,记录一下。

一、qsort介绍(参考百度和CSDN博客)

    qsort是在C函数库(stdlib.bi)里实现的快速排序函数,是根据二分法写的,其时间复杂度为n*log(n)。其函数原型为:

sub qsort (byval base as any ptr, byval num as size_t, byval nWidth as size_t, byval pCompare as function(byval as any ptr, byval as any ptr) as long)

    base是待排序的数组基址,num是数组元素个数,nwidth是数组元素的大小(以字节为单位),pCompare为函数指针,指向一个自定义的比较函数,需要根据自己的需求编写。

    自定义比较函数原型如下:

function 函数名 cdecl(byval a as any ptr, byval b as any ptr) as long

    函数名可以随意定义,但函数中的cdecl关键字必须声明,因为是调用的C库,所以必须声明cdecl调用方式,否则出错。a和b为两个待比较的数,可以是整数、小数、字符串、结构体等,根据自己的需要进行排序,比较规则如下:

    1、如果a排在b前面,则函数返回值为负整数(-1)

    2、如果a和b哪个排在前面都行,则函数返回值为0

    3、如果a排在b后面,则函数返回值为正整数(1)
二、示例

    VFB窗体界面:

FreeBASIC调用qsort排序_第1张图片

因为要使用C函数库,所以我们要引用头文件,一般在工程选项卡的特殊函数目录的FF_AppStart文件里添加。位置如图:

FreeBASIC调用qsort排序_第2张图片

添加头文件:

#Include Once "crt\stdlib.bi"
#Include Once "crt\string.bi"  '需要用到strcmp函数

代码如下:

#define BUFFER_SIZE 20   '定义排序数组大小

'整型数排序
function cmpInt cdecl(byval a as any ptr, byval b as any ptr) as long
    Return *Cast(long ptr,a) - *Cast(long Ptr,b)
End Function

Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)  '单击
    Dim a(BUFFER_SIZE - 1) As long
    Print "生成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Randomize                 '随机数种子
        a(i) = int(Rnd * 100000)  '随机数
        Print a(i),
    Next
    print
    Print "排序"
    qsort(@a(0),BUFFER_SIZE, SizeOf(long),@cmpInt) 
    Print "排序完成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Print a(i),
    Next
    print
End Sub

'浮点型排序
function cmpDbl cdecl(byval a as any ptr, byval b as any ptr) as long
    Dim c As Double Ptr = Cast(Double Ptr, a)   '需要先转换类型保存
    Dim d As Double Ptr = Cast(Double Ptr, b)
    
    return IIf(*c > *d,1,-1)                    '比较
End Function

Sub Form1_Command2_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)  '单击
    Dim a(BUFFER_SIZE - 1) As Double
    Print "生成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Randomize                 '随机数种子
        a(i) = Rnd * 100000  '随机数
        Print a(i),
    Next
    print
    Print "排序"
    qsort(@a(0),BUFFER_SIZE, SizeOf(Double),@cmpDbl) 
    Print "排序完成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Print a(i),
    Next
    print
End Sub

'字符串排序
function cmpStr cdecl(byval a as any ptr, byval b as any ptr) as long
    Dim c As ZString Ptr = Cast(ZString Ptr, a)
    Dim d As ZString Ptr = Cast(ZString Ptr, b)
    return strcmp(c,d)
End Function

Sub Form1_Command3_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)  '单击
    Dim s As String = "0123456789"
    Dim a(BUFFER_SIZE - 1) As ZString * 10    '字符串使用ZString比较方便用于C函数库的排序
    Print "生成"
    For i As Long = 0 To BUFFER_SIZE - 1
        For j As Long = 0 To 5
            Randomize                 '随机数种子
            a(i) &= Mid(s,int(Rnd * 10) + 1,1)   '随机数
        Next j
        Print a(i), 
    Next
    print
    Print "排序"
    qsort(@a(0),BUFFER_SIZE, SizeOf(ZString * 10),@cmpStr) 
    Print "排序完成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Print a(i),
    Next
    print    
End Sub

'结构体排序
Type Student          '学生结构
    ID As Long        '学号
    Name As String    '名字
    Score As Long     '分数 
End Type

function cmpType cdecl(byval a as any ptr, byval b as any ptr) as long
    Dim c As Student Ptr = Cast(Student Ptr, a)
    Dim d As Student Ptr = Cast(Student Ptr, b)
    
    Return c->Score - d->Score  '用分数排名 从小到大
End Function

Sub Form1_Command4_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)  '单击
    Dim a(BUFFER_SIZE - 1) As Student
    Print "生成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Randomize                 '随机数种子
        a(i).ID = int(Rnd * 10000)  '随机数
        a(i).Name = "张三" & i & "号" 
        Randomize                 '随机数种子
        a(i).Score = Int(Rnd * 120 + 1)
        Print a(i).ID,a(i).Name,a(i).Score
    Next
    print
    Print "排序"
    qsort(@a(0),BUFFER_SIZE, SizeOf(Student),@cmpType) 
    Print "排序完成"
    For i As Long = 0 To BUFFER_SIZE - 1
        Print a(i).ID,a(i).Name,a(i).Score
    Next
    print
End Sub

运行效果:

整型数:

FreeBASIC调用qsort排序_第3张图片

浮点型:

FreeBASIC调用qsort排序_第4张图片

字符串:(为了方便看出来,使用的是数字字符串)

FreeBASIC调用qsort排序_第5张图片

结构体:

FreeBASIC调用qsort排序_第6张图片

完整代码:

https://github.com/rainheart311/VisualFreeBASIC/tree/master/qsort

你可能感兴趣的:(FreeBASIC随记)