转载 快速排序法VB和VBA版、递归法版 vba 数组排序函数

先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为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)排序法的内容,同时,对本文中的部分地方进行修改,大家别丢砖头哈。

先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为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)排序法的内容,同时,对本文中的部分地方进行修改,大家别丢砖头哈。

  

爱华网本文地址 » http://www.aihuau.com/a/25101012/129181.html

更多阅读

红米1S电信版和移动版和联通版的区别 红米1s移动版破解联通

红米1S电信版和移动版和联通版的区别——简介 直到今天,发烧级平民手机红米手机各种移动运营商制式总算全部发布起了!这也给不是IT行业的朋友选购带来了纠结,哪一版本适合自己呢?各个版本有什么全部呢?今天小编为你一一解析!希望能给你提

iphone4美版和港版的区别 ps4游戏港版美版区别

iphone4美版和港版的区别——简介 iphone4美版和港版的区别iphone4美版和港版的区别——方法/步骤iphone4美版和港版的区别 1、版本 美版iphone4分为无锁版与有锁版 (有锁版中有份为电信写号版与普通卡贴版 )港版的都为无锁版iphone

声明:《转载 快速排序法VB和VBA版、递归法版 vba 数组排序函数》为网友風铃無聲分享!如侵犯到您的合法权益请联系我们删除