转载 快速排序法VB和VBA版、递归法版 vba 数组排序函数
在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止
快速排序的基本思想是基于分治策略的。对于输入的子序列L[p..r],如果规模足够小则直接进行排序(比如用前述的冒泡、选择、插入排序均可),否则分三步处理:
分解(Divide):将待排序列L[p..r]划分为两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值。具体可通过这样的途径实现:在序列L[p..r]中选择数据元素L[q],经比较和移动后,L[q]将处于L[p..r]中间的适当位置,使得数据元素L[q]的值小于L[q+1..r]中任一元素的值。
递归求解(Conquer):通过递归调用快速排序算法,分别对L[p..q]和L[q+1..r]进行排序。
合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在L[p..q]和L[q+1..r]都排好序后不需要执行任何计算L[p..r]就已排好序,即自然合并。
对于基数基本是取最左边一位、最中间一位或最后一位,后面的代码小Y按最中间那位做为基数,进行递归排序。另外:小Y是非计算机专业的,有些坏毛病总是改不过来,习惯于把数组的最小的下标设置为“1”。
Option Base 1
Public Sub Qsort(first As Long, last As Long, dtlist() As Long)
Dim i As Long
Dim j As Long
Dim mid As Long
Dim save As Long
i = first
j = last
mid = dtlist((first + last) / 2)
Do
Do While mid > dtlist(i)
i = i + 1
Loop
Do While mid < dtlist(j)
j = j - 1
Loop
If i <= j Then
save = dtlist(i)
dtlist(i) = dtlist(j)
dtlist(j) = save
i = i + 1
j = j - 1
End If
Loop Until i > j
If first < j Then Call Qsort(first, j, dtlist)
If i < last Then Call Qsort(i, last, dtlist)
End Sub
该段代码如果是EXCEL的VBA中,应写成模块级,以便在别的地方能更好的调用。
然后小Y在一个工作表的代码区写下了如下代码,以在立即窗口进行检测(没有再次使用产生随机数的办法,虽然自己赋值麻烦,但是能较好的达到自己的目的)。同时,建议把数组量缩小,最好是三到五位,按单步运行代码,能更好的学习下面的代码。其实说真的,我总觉得这些在实际中用处较小,如果数据量过大,为何不通过ADO放到数据库里进行排序,然后再返回到EXCEL表或别的地方呢?更有过份的朋友,通过CopyMemory虚拟指针来对一大串的字符串进行排序,感觉特别麻烦,而且递归法小Y一直不喜欢用,虽然速度很快,但是一旦数据上量了,就需要手动修改堆栈的数量。
Option Base 1
Sub test1()
Dim a(10) As Long
a(1) = 4
a(2) = 1
a(3) = 9
a(4) = 99
a(5) = 21
a(6) = 14
a(7) = 22
a(8) = 100
a(9) = 35
a(10) = 3
Call Qsort(LBound(a()), UBound(a()), a())
For i = LBound(a()) To UBound(a())
Debug.Print a(i)
Next
End Sub
前两天听清华大学严蔚敏教授讲《数据结构》时听到一句明言:算法+数据结构=程序,这也是小Y回头过来再次学习算法的一个原因。准备听《经济法了》,明天上午再加上希尔(shell)排序法的内容,同时,对本文中的部分地方进行修改,大家别丢砖头哈。
先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1, 处理结束。
在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止
快速排序的基本思想是基于分治策略的。对于输入的子序列L[p..r],如果规模足够小则直接进行排序(比如用前述的冒泡、选择、插入排序均可),否则分三步处理:
分解(Divide):将待排序列L[p..r]划分为两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值。具体可通过这样的途径实现:在序列L[p..r]中选择数据元素L[q],经比较和移动后,L[q]将处于L[p..r]中间的适当位置,使得数据元素L[q]的值小于L[q+1..r]中任一元素的值。
递归求解(Conquer):通过递归调用快速排序算法,分别对L[p..q]和L[q+1..r]进行排序。
合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在L[p..q]和L[q+1..r]都排好序后不需要执行任何计算L[p..r]就已排好序,即自然合并。
对于基数基本是取最左边一位、最中间一位或最后一位,后面的代码小Y按最中间那位做为基数,进行递归排序。另外:小Y是非计算机专业的,有些坏毛病总是改不过来,习惯于把数组的最小的下标设置为“1”。
Option Base 1
Public Sub Qsort(first As Long, last As Long, dtlist() As Long)
Dim i As Long
Dim j As Long
Dim mid As Long
Dim save As Long
i = first
j = last
mid = dtlist((first + last) / 2)
Do
Do While mid > dtlist(i)
i = i + 1
Loop
Do While mid < dtlist(j)
j = j - 1
Loop
If i <= j Then
save = dtlist(i)
dtlist(i) = dtlist(j)
dtlist(j) = save
i = i + 1
j = j - 1
End If
Loop Until i > j
If first < j Then Call Qsort(first, j, dtlist)
If i < last Then Call Qsort(i, last, dtlist)
End Sub
该段代码如果是EXCEL的VBA中,应写成模块级,以便在别的地方能更好的调用。
然后小Y在一个工作表的代码区写下了如下代码,以在立即窗口进行检测(没有再次使用产生随机数的办法,虽然自己赋值麻烦,但是能较好的达到自己的目的)。同时,建议把数组量缩小,最好是三到五位,按单步运行代码,能更好的学习下面的代码。其实说真的,我总觉得这些在实际中用处较小,如果数据量过大,为何不通过ADO放到数据库里进行排序,然后再返回到EXCEL表或别的地方呢?更有过份的朋友,通过CopyMemory虚拟指针来对一大串的字符串进行排序,感觉特别麻烦,而且递归法小Y一直不喜欢用,虽然速度很快,但是一旦数据上量了,就需要手动修改堆栈的数量。
Option Base 1
Sub test1()
Dim a(10) As Long
a(1) = 4
a(2) = 1
a(3) = 9
a(4) = 99
a(5) = 21
a(6) = 14
a(7) = 22
a(8) = 100
a(9) = 35
a(10) = 3
Call Qsort(LBound(a()), UBound(a()), a())
For i = LBound(a()) To UBound(a())
Debug.Print a(i)
Next
End Sub
前两天听清华大学严蔚敏教授讲《数据结构》时听到一句明言:算法+数据结构=程序,这也是小Y回头过来再次学习算法的一个原因。准备听《经济法了》,明天上午再加上希尔(shell)排序法的内容,同时,对本文中的部分地方进行修改,大家别丢砖头哈。
先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1, 处理结束。
在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止
快速排序的基本思想是基于分治策略的。对于输入的子序列L[p..r],如果规模足够小则直接进行排序(比如用前述的冒泡、选择、插入排序均可),否则分三步处理:
分解(Divide):将待排序列L[p..r]划分为两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值。具体可通过这样的途径实现:在序列L[p..r]中选择数据元素L[q],经比较和移动后,L[q]将处于L[p..r]中间的适当位置,使得数据元素L[q]的值小于L[q+1..r]中任一元素的值。
递归求解(Conquer):通过递归调用快速排序算法,分别对L[p..q]和L[q+1..r]进行排序。
合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在L[p..q]和L[q+1..r]都排好序后不需要执行任何计算L[p..r]就已排好序,即自然合并。
对于基数基本是取最左边一位、最中间一位或最后一位,后面的代码小Y按最中间那位做为基数,进行递归排序。另外:小Y是非计算机专业的,有些坏毛病总是改不过来,习惯于把数组的最小的下标设置为“1”。
Option Base 1
Public Sub Qsort(first As Long, last As Long, dtlist() As Long)
Dim i As Long
Dim j As Long
Dim mid As Long
Dim save As Long
i = first
j = last
mid = dtlist((first + last) / 2)
Do
Do While mid > dtlist(i)
i = i + 1
Loop
Do While mid < dtlist(j)
j = j - 1
Loop
If i <= j Then
save = dtlist(i)
dtlist(i) = dtlist(j)
dtlist(j) = save
i = i + 1
j = j - 1
End If
Loop Until i > j
If first < j Then Call Qsort(first, j, dtlist)
If i < last Then Call Qsort(i, last, dtlist)
End Sub
该段代码如果是EXCEL的VBA中,应写成模块级,以便在别的地方能更好的调用。
然后小Y在一个工作表的代码区写下了如下代码,以在立即窗口进行检测(没有再次使用产生随机数的办法,虽然自己赋值麻烦,但是能较好的达到自己的目的)。同时,建议把数组量缩小,最好是三到五位,按单步运行代码,能更好的学习下面的代码。其实说真的,我总觉得这些在实际中用处较小,如果数据量过大,为何不通过ADO放到数据库里进行排序,然后再返回到EXCEL表或别的地方呢?更有过份的朋友,通过CopyMemory虚拟指针来对一大串的字符串进行排序,感觉特别麻烦,而且递归法小Y一直不喜欢用,虽然速度很快,但是一旦数据上量了,就需要手动修改堆栈的数量。
Option Base 1
Sub test1()
Dim a(10) As Long
a(1) = 4
a(2) = 1
a(3) = 9
a(4) = 99
a(5) = 21
a(6) = 14
a(7) = 22
a(8) = 100
a(9) = 35
a(10) = 3
Call Qsort(LBound(a()), UBound(a()), a())
For i = LBound(a()) To UBound(a())
Debug.Print a(i)
Next
End Sub
前两天听清华大学严蔚敏教授讲《数据结构》时听到一句明言:算法+数据结构=程序,这也是小Y回头过来再次学习算法的一个原因。准备听《经济法了》,明天上午再加上希尔(shell)排序法的内容,同时,对本文中的部分地方进行修改,大家别丢砖头哈。
更多阅读
红米1S电信版和移动版和联通版的区别 红米1s移动版破解联通
红米1S电信版和移动版和联通版的区别——简介 直到今天,发烧级平民手机红米手机各种移动运营商制式总算全部发布起了!这也给不是IT行业的朋友选购带来了纠结,哪一版本适合自己呢?各个版本有什么全部呢?今天小编为你一一解析!希望能给你提
天天风之旅 如何快速得到装备碎片和巨人模式 座敷童子碎片快速获得
【天天风之旅】如何快速得到装备碎片和巨人模式——简介天天风之旅免费获得装备的其中一个途径就是获得装备碎片。后期跑得远能遇到碎片,但是前期体力有限的情况下如何快速刷出装备碎片。尤其前期有个任务“完成一次用装备碎片抽取装
iphone4美版和港版的区别 ps4游戏港版美版区别
iphone4美版和港版的区别——简介 iphone4美版和港版的区别iphone4美版和港版的区别——方法/步骤iphone4美版和港版的区别 1、版本 美版iphone4分为无锁版与有锁版 (有锁版中有份为电信写号版与普通卡贴版 )港版的都为无锁版iphone
Photoshop新手如何快速新建图层和复制多个图层 ps复制选区并新建图层
Photoshop新手如何快速新建图层和复制多个图层——简介图层面板可以说是PS的核心,可以缩放、更改颜色、设置样式、改变透明度,等等等等。Photoshop新手如何快速新建图层和复制多个图层——工具/原料一台电脑安装好的photoshop软件P
英语单词记忆法,四种有效的英语单词快速记忆法 五线谱快速记忆法
有没有好的英语单词记忆法,让我们可以告别死记硬背,低效率的英语单词记忆法,在这里我们为您推荐了四种有效的英语单词快速记忆法希望能对广大学生有所帮助。 英语中英语单词学习是英语学习之本,充足的英语单词量是有效进行听、说、读和