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閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容

  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    蟻前閱讀 5,211評論 0 52
  • 概述:排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,740評論 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,270評論 0 2
  • 總結一下常見的排序算法。 排序分內排序和外排序。內排序:指在排序期間數據對象全部存放在內存的排序。外排序:指在排序...
    jiangliang閱讀 1,369評論 0 1
  • 參考博客: iOS開發~CocoaPods使用詳細說明 用CocoaPods做iOS程序的依賴管理 CocoaPo...
    abletyang閱讀 33,227評論 5 29