首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

快速排序(有请高手)解决方案

2012-01-19 
快速排序(有请高手)闲来无事,写了一个快速排序的子程序,请大家指正,谢谢!OptionExplicitPrivateSubQuickSo

快速排序(有请高手)
闲来无事,写了一个快速排序的子程序,请大家指正,谢谢!

Option   Explicit

Private   Sub   QuickSort(Arr()   As   String,   ByVal   nStar   As   Integer,   ByVal   nEnd   As   Integer)
  Dim   Atmp()   As   Single,   vMid   As   Single
'Dim   Atmp()   As   String,   vMid   As   String     '用于排序字符串
Dim   i   As   Integer,   nMid   As   Integer,   nMin   As   Integer,   nMax   As   Integer

ReDim   Atmp(nEnd   -   nStar)
nMin   =   nStar:   nMax   =   nEnd
For   i   =   nStar   To   nEnd
Atmp(i   -   nStar)   =   Val(Arr(i))
Next
nMid   =   (nEnd   +   nStar)   \   2
vMid   =   Val(Arr(nMid))

For   i   =   nStar   To   nEnd
        If   i   =   nMid   Then   i   =   i   +   1
        If   Atmp(i   -   nStar)   <   vMid   Then
                Arr(nMin)   =   Atmp(i   -   nStar)
                nMin   =   nMin   +   1
        Else
                Arr(nMax)   =   Atmp(i   -   nStar)
                nMax   =   nMax   -   1
        End   If
Next

Arr(nMax)   =   vMid
If   nMin   -   nStar   >   nEnd   -   nMax   Then   nMin   =   nMax   -   1   Else   nMax   =   nMin   +   1

If   nMin   >   nStar   Then   QuickSort   Arr,   nStar,   nMin
If   nEnd   >   nMax   Then   QuickSort   Arr,   nMax,   nEnd
End   Sub

Private   Sub   Form_Load()
Const   srcStr   As   String   =   "9,15,2,0,1,8,41,999,500,321,123 "
Dim   Arr()   As   String
Arr   =   Split(srcStr,   ", ")
QuickSort   Arr,   0,   UBound(Arr)
MsgBox   Join(Arr,   ", ")   &   vbLf   &   srcStr
End   Sub


[解决办法]
思路就是一般的快速排序

从队列种任意选择一个参照元
将剩下的数跟参照元比较,分为2组,一组比参照元小,一组比参照元大
对分开的2组递归的进行上面的流程,直到队列只剩一个数
最后获得排序队列

没有太仔细的看,不过,快速排序的优化一般是考虑
1 在队列小于20的情况下,不再递归的使用快速排序,而是使用插入排序代替
2 优化参照元的选取,应该会有比选择队列中点更好的选择办法

快速排序是所谓的“已知实践中表现最好但是从来就不能被正确的编程”的排序方法
[解决办法]
思路原来有了,今天上午有空,一早起来,弄了半天,也算写出一个,效率应该还可以吧:

Private Sub TestSort(ByRef mSort() As String)

Dim i As Long, j As Long, k As Long
Dim min As Long, max As Long
Dim b() As Integer

min = mSort(LBound(mSort))
max = min
k = 0
j = 0

For i = LBound(mSort) To UBound(mSort)
If mSort(i) > max Then max = mSort(i)
If mSort(i) < min Then min = mSort(i)
Next i

ReDim b(max)
For i = LBound(mSort) To UBound(mSort)
b(mSort(i)) = b(mSort(i)) + 1


Next i

For i = min To max
If b(i) > 0 Then
For j = k To k + b(i) - 1
mSort(j) = i
Next j
k = k + b(i)
End If
Next i

End Sub
[解决办法]
如果我没看错,vbman2003(家人)贴的应该是计数算法。网上介绍说,“对于使用比较法作为算法基础的算法来说,最快需N * log(N)步才能完成排序。计数排序法不作用比较,所以它不受此限制。实际上该算法是如此之快,以致于你会认为是使用了魔术,而不是数学运算来排序。 另一方面,计数排序法只能用于特殊的情况。首先,所有的要进行排序的数据必须是整数,不能对字符使用该算法;其次,数据的范围有限,如果你的数据是在1到1000之内,用这种算法的效果就非常好,但如果你的数据是在1到30000之间,该算法就根本不能用。”
如果你希望排序后去掉数组中的重复值,那就用它吧。只需改一下,还省事。
我在想这个算法的关键在于数组找它的元素非常快,b(mSort(i)) = b(mSort(i)) + 1。如果它是:
Do
If Min = mSort(i) Then
所求 = b(Min) + 1
Exit Do
Else
Min = Min + 1
End If
Loop
想来它的速度也不会快到哪里去。不知道数组找它的元素为什么这么快。
关于小数,网上介绍了一种二维数组的方法:“遇到的数据具有以下特征:①相同数据很多,②最大、最小数之间相差不到3,③都是带两位小数的正数。
针对数据的特征,我采用了以下算法:
步骤:
1. 用一个循环找出整数和小数部分的最大、最小值。小数部分的最大、最小值乘以100转为整数。
2. 定义一个二维数组,下标范围分别是整数和小数部分的最小值到最大值。
3. 再用一个循环把所有源数据填入刚才定义的二维数组,填写规则是,源数据的整数和小数部分分别对应二维数组的两个下标。例如,“13.51 "填到“A(13,51) "中。
4. 最后顺向或逆向读取二维数组中的非零数据即可得到从小到大或从大到小排列的数据,而且不会含有重复数据。”
转贴网上的计数算法:
首先该算法创建一个整数类型的临时数组,该数组的上下标分别是要排序的数据的最大最小值。如果数据列表的最大最小值从min_item到max_item, 该算法就将数组创建成下面这样:
Dim Counts() As Integer

ReDim Counts(min_item To max_item)接下来,算法检查列表中的每一个项目,并增加对应该项目的数组元素的值,当这一阶段完成后,Counts(I)的数值就是就是数值为I的基础上的个数。
For I = min To Max
Counts(List(I)) = Counts(List(I)) + 1
Next I程序扫描Counts数组,将counts转换成被排序列表中的偏移量。
next_spot = 1
For i = min_value To max_value
this_count = counts(i)
counts(i) = next_spot
next_spot = next_spot + this_count
Next i最后将数据进行排序
下面是实现该算法的VB代码

Sub Countingsort (List() As Long, sorted_list() As Long, _
min As Integer, max As Integer, min_value As Long, _
max_value As Long)
Dim counts() As Integer
Dim i As Integer
Dim this_count As Integer
Dim next_offset As Integer

' Create the Counts array.
ReDim counts(min_value To max_value)

' Count the items.
For i = min To max
counts(List(i)) = counts(List(i)) + 1
Next i

' Convert the counts into offsets.
next_offset = min
For i = min_value To max_value
this_count = counts(i)
counts(i) = next_offset
next_offset = next_offset + this_count
Next i

' Place the items in the sorted array.
For i = min To max
sorted_list(counts(List(i))) = List(i)
counts(List(i)) = counts(List(i)) + 1
Next i
End Sub

热点排行