VB程序设计

VB程序设计

VB6.0似乎已经成为开发者的往事,但是Microsoft Office系列软件的控制和操作仍然是基于VB6.0的。本项目是为所有学习VB6.0的同学而建立的。

问题1: 排序算法

排序算法是计算机程序设计中最经典的算法,在计算机的专业课《数据结构》中有大量的讨论和分析。我们在这里只讨论最简单的选择排序冒泡排序。讨论从一个填空题开始。

' 功能:将数组a()中的元素按从小到大排序'
' 参数:数组a()的下标索引为从1到30'
Sub bubble_sort(a() As Integer)
    For i = 1 To 29
        For j = 【2】
            If a(i) > a(j) Then
                m = a(i): a(i) = a(j): a(j) = m
            End If
        Next j
    Next i
End Sub

问题:【2】这个地方应该填什么?是 i+1 To 30?还是 1 To 30-i?

  • 首先,最正确的姿势是记住!甭管是冒泡还是选择排序,这里j的取值应该与i正好错开1,【2】处应该填:i+1 To 30
  • 其次,理解排序的原理。为什么不是:1 To 30-i呢?
    首先,我们要明确目标。因为要对数组a()从小到大排序,我们期望:依次扫描a()中的每个元素,每扫描到一个元素a(i),都使得它是剩下的元素(从a(i)到a(30))中最小的。怎么做到呢?可以从a(i)一直扫描到a(30),找到最小的元素a(p),令a(i)和a(p)的值交换(注意:这里不能直接让a(i)=a(p),否则,a(i)的原有值就不见了)。用下面的伪代码表示:
'代码块1
Sub selection_sort(a() As Integer)
    For i = 1 To 30
        '从a(i) 到 a(30)中找到最小的元素a(p)'
        '将a(i)和a(p)的值交换'
    Next i
End Sub

那么,怎么从a(i) 到 a(30)中找到最小的元素a(p)呢?可以这样做:

'代码块2
p = a(i) '首先,假设a(i)就是最小的'
For j = i To 30 '从a(i) 扫描到 a(30)'
    If p > a(j) Then '一旦发现p比a(j)还大,就让p指向a(j)'
        p = a(j)
    End If
Next j

上述做法,就是选择排序的思想。我们可以将代码优化下:
首先,j 不必从 i 开始扫描,因为当 j = i 时,a(j)没有必要跟a(p)进行比较(这时,p 也等于 i)。
其次,p 指向a(i)的索引就可以了,没有必要指向a(i)。

'代码块3
p = i ' 假设a(i)就是最小的
For j = i+1 To 30
    If a(p) > a(j) Then  '一旦发现a(p)比a(j)还大,就让 p 指向 j
        p = j
    End If
Next j

这时,将代码块3嵌入代码块1,就可以得到完整的选择排序的代码了:

'代码块4
Sub selection_sort(a() As Integer)
    For i = 1 To 30
        '从a(i) 到 a(30)中找到最小的元素a(p)
        p = i '假设a(i)就是最小的
        For j = i+1 To 30
            If a(p) > a(j) Then '一旦发现a(p)比a(j)还大,就让 p 指向 j
                p = j
            End If
        Next j
        '将a(i)和a(p)的值交换(代码略)'
    Next i
End Sub
  • 经过上面的推演,我们就得到了一个双重循环。反过来,如果直接拿到的就是这样一个双重循环的话,会不会感觉阅读起来很困难?实际上,只要把外层循环 i 固定为某个特定的值来理解内层循环 j 就可以了。
  • 再来看冒泡排序法。它与选择排序法最大的不同在于:在其内层循环 j 中,一旦发现a(p)比a(j)还大,就让 a(p) 和 a(j) 的值交换,而 p 是始终指向 i 的(因为a(p)中一直存放最小的值,所以,p就没有必要再移动了)。这样,每经过一次内层循环,就相当于剩下元素中具有最小值的那个元素(具有最小的质量)从水底下浮出来了,因此称为“冒泡排序法”。具体代码如下:
' 代码块5
Sub selection_sort(a() As Integer)
    For i = 1 To 30
        ' 从a(i) 到 a(30)中找到最小的元素a(p)
        ' 假设a(i)就是最小的,并且始终存放剩余元素中的最小值
        For j = i+1 To 30
            If a(i) > a(j) Then '一旦发现a(i)比a(j)还大,就让它们交换
                m = a(i): a(i) = a(j) : a(j) = m
            End If
        Next j
    Next i
End Sub
  • 那么,上面的“选择排序”和“冒泡排序”哪个更优呢?也就是,哪个排序算法的速度更快呢?显然是选择排序。因为冒泡排序在最坏的情况下需要 30-(i+1)+1=30-i 次 a(j) 和 a(i) 的交换,而选择排序只要交换交换 1 次即可。
  • 再来看同学的问题,同学尝试将内层循环 j 设置为 1 To 30-i 有什么问题呢?事实上,这样做就意味着:该做的没有做,不该做的却费力去做。第一,该做的没有做。你看,这样做只能找到从a(1)到a(30-i)中的最小值,那a(30-i)之后的元素呢?第二,不该做的却费力去做。为了让 a(i) 为剩下元素中的最小值,还需要做许多冗余的工作:它还要跟它之前的已经比它还小的元素依次比较,这完全是没有必要的,因为比它大的元素,只可能在它后边。
  • 练习。如果我们非要将内层循环 j 设置为 1 To 30-i 呢?如果非要这样做,外层循环 i 的设置必须改变,它必须从 a(i) 的最后一个元素倒着走向 a(i) 的第一个元素,以保证:每次a(i)中都存放最大值。这样的程序该如何写?请同学们自行练习。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,149评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,723评论 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 1,225评论 0 2
  • 总结一下常见的排序算法。 排序分内排序和外排序。内排序:指在排序期间数据对象全部存放在内存的排序。外排序:指在排序...
    jiangliang阅读 1,310评论 0 1
  • 参考博客: iOS开发~CocoaPods使用详细说明 用CocoaPods做iOS程序的依赖管理 CocoaPo...
    abletyang阅读 33,165评论 5 29