亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 第3章 排序與查找.txt

?? 我自己整理的c語言教程 來自 c語言之家
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
C語言編程常見問題解答  
 

 
發表日期:2003年9月22日    作者:C語言之家整理  已經有3830位讀者讀過此文 
 


                                    第3章  排序與查找

    在計算機科學中,排序(sorting)是研究得最多的問題之一,許多書籍都深入討論了這個問題。本章僅僅是一個介紹,重點放在C語言的實際應用上。

    排 序

    程序員可以使用的基本排序算法有5種:
    ·插入排序(insertionsort.)
    ·交換排序(exchangesOrt)
    ·選擇排序(selectionsort)    
    ·歸并排序(mergesort)
    ·分布排序(distributionsort)

    為了形象地解釋每種排序算法是怎樣工作的,讓我們來看一看怎樣用這些方法對桌上一付亂序的牌進行排序。牌既要按花色排序(依次為梅花、方塊、紅桃和黑心),還要按點數排序(從2到A)。
    插入排序的過程為:從一堆牌的上面開始拿牌,每次拿一張牌,按排序原則把牌放到手中正確的位置。桌上的牌拿完后,手中的牌也就排好序了。
    交換排序的過程為:
    (1)先拿兩張牌放到手中。如果左邊的牌要排在右邊的牌的后面,就交換這兩張牌的位置。
    (2)然后拿下一張牌,并比較最右邊兩張牌,如果有必要就交換這兩張牌的位置。
    (3)重復第(2)步,直到把所有的牌都拿到手中。
    (4)如果不再需要交換手中任何兩張牌的位置,就說明牌已經排好序了;否則,把手中的牌放到桌上,重復(1)至(4)步,直到手中的牌排好序。
    選擇排序的過程為:在桌上的牌中找出最小的一張牌,拿在手中;重復這種操作,直到把所有牌都拿在手中。
    歸并排序的過程為:把桌上的牌分為52堆,每堆為一張牌。因為每堆牌都是有序的(記住,此時每堆中只有一張牌),所以如果把相鄰的兩堆牌合并為一堆,并對每堆牌進行排序,就可以得到26堆已排好序的牌,此時每一堆中有兩張牌。重復這種合并操作,就可以依次得到13堆牌(每一堆中有4張牌),7堆牌(有6堆是8張牌,還有一堆是4張牌),最后將得到52張的一堆牌。
    分布排序(也被稱作radix sort,即基數排序)的過程為:先將牌按點數分成13堆,然后將這13堆牌按點數順序疊在一起;再將牌按花色分成4堆,然后將這4堆牌按花色順序疊在一起,牌就排好序了。
    在選用排序算法時,你還需要了解以下幾個術語:
    (1)自然的(natural)
    如果某種排序算法對有序的數據排序速度較快(工作量變小),對無序的數據排序速度卻較慢(工作變量大),我們就稱這種排序算法是自然的。如果數據已接近有序,就需要考慮選用自然的排序算法。
    (2)穩定的(stable)
    如果某種排序算法能保持它認為相等的數據的前后順序,我們就稱這種排序算法是穩定的。    
    例如,現有以下名單:
    Mary Jones
    Mary Smith
    Tom Jones
    Susie Queue
    如果用穩定的排序算法按姓對上述名單進行排序,那么在排好序后"Mary Jones”和"Tom Jones”將保持原來的Jr順序,因為它們的姓是相同的。
    穩定的排序算法可按主、次關鍵字對數據進行排序,例如按姓和名排序(換句話說,主要按姓排序,但對姓相同的數據還要按名排序)。在具體實現時,就是先按次關鍵字排序,再按主關鍵字排序。
    (3)內部排序(internal sort)和外部排序(external sort)
    待排數據全部在內存中的排序方法被稱為內部排序,待排數據在磁盤、磁帶和其它外存中的排序方法被稱為外部排序。

    查 找

    和排序算法一樣,查找(searching)算法也是計算機科學中研究得最多的問題之一。查找算法和排序算法是有聯系的,因為許多查找算法依賴于要查找的數據集的有序程度。基本的查找算法有以下4種:
    ·順序查找(sequential searching)。
    ·比較查找(comparison searching)
    ·基數查找(radix searching)
    ·哈希查找(hashing)    
    下面仍然以一付亂序的牌為例來描述這些算法的工作過程。
    順序查找的過程為:從第一張開始查看每一張牌,直到找到要找的牌。
    比較查找(也被稱作binarysearching,即折半查找)要求牌已經排好序,其過程為:任意抽一張牌,如果這張牌正是要找的牌,則查找過程結束。如果抽出的這張牌比要找的牌大,則在它前面的牌中重復查找操作;反之,則在它后面的牌中重復查找操作,直到找到要找的牌。
    基數查找的過程為:先將牌按點數分成13堆,或者按花色分成4堆。然后找出與要找的牌的點數或花色相同的那一堆牌,再在這堆牌中用任意一種查找算法找到要找的牌。
    哈希查找的過程為:
    (1)在桌面上留出可以放若干堆牌的空間,并構造一個函數,使其能根據點數和花色將牌映射到特定的堆中(這個函數被稱為hashfunction,即哈希函數)。
    (2)根據哈希函數將牌分成若干堆。    
    (3)根據哈希函數找到要找的牌所在的堆,然后在這一堆牌中找到要找的牌。    
    例如,可以構造這樣一個哈希函數:    
  pile=rank+suit
    其中,rank是表示牌的點數的一個數值;suit是表示牌的花色的一個數值;pile表示堆值,它將決定一張牌歸入到哪一堆中。如果用1,2,……,13分別表示A,2,…….K,用0,1,2和3分別表示梅花、方塊、紅桃和黑桃,則pile的值將為1,2,……,16,這樣就可以把一付牌分成16堆。
    哈希查找雖然看上去有些離譜,但它確實是一種非常實用的查找算法。各種各樣的程序,從壓縮程序(如Stacker)到磁盤高速緩存程序(如SmartDrive),幾乎都通過這種方法來提高查找速度,
    
  排序或查找的性能
    
  有關排序和查找的一個主要問題就是速度。這個問題經常被人們忽視,因為與程序的其余部分相比,排序或查找所花費的時間幾乎可以被忽略。然而,對大多數排序或查找應用來說,你不必一開始就花很多精力去編制一段算法程序,而應該先在現成的算法中選用一種最簡單的(見3.1和3.4),當你發現所用的算法使程序運行很慢時,再換用一種更好的算法(請參見下文中的介紹)。
    下面介紹一種判斷排序或查找算法的速度的方法。
    首先,引入一個算法的復雜度的概念,它指的是在各種情況(最好的、最差的和平均的)下排序或查找需要完成的操作次數,通過它可以比較不同算法的性能。
    算法的復雜度與排序或查找所針對的數據集的數據量有關,因此,引入一個基于數據集數據量的表達式來表示算法的復雜度。
    最快的算法的復雜度O(1),它表示算法的操作次數與數據量無關。復雜度O(N)(N表示數據集的數據量)表示算法的操作次數與數據量直接相關。復雜度O(logN)介于上述兩者之間,它表示算法的操作次數與數據量的對數有關。復雜度為O(NlogN)(N乘以logN)的算法比復雜度為O(N)的算法要慢,而復雜度為O(N2)的算法更慢。 
    注意:如果兩種算法的復雜度都是O(logN),那么logN的基數較大的算法的速度要快些,在本章的例子中,logN的基數均為10。

        表3.1  本章所有算法的復雜度
-----------------------------------------------------------------
    算    法    最好情況    平均情況    最壞情況
-----------------------------------------------------------------
  快速排序      O(NlogN)    O(NlogN)    O(N2)
  歸并排序      O(N)        O(NlogN)    O(NlogN)
  基數排序      O(N)        O(N)        O(N)    
  線性查找                  O(N)
  折半查找                  O(NlogN)
  哈希查找                  O(N/M)*
  健樹查找                  O(1)**
-----------------------------------------------------------------
* M是哈希表項的數目
** 實際上相當于有232個哈希表項的哈希查找

    表3. 1列出了本章所有算法的復雜度。對于排序算法,表中給出了最好的、平均的和最差的情況下的復雜度,平均情況是指數據隨機排列的情況;排序算法的復雜度視數據的初始排列情況而定,它一般介于最好的和最差的兩種情況之間。對于查找算法,表中只給出了平均情況下的復雜度,在最好的情況(即要找的數據恰好在第一次查找的位置)下,查找算法的復雜度顯然是O(1);在最壞的情況(即要找的數據不在數據集中)下,查找算法的復雜度通常與平均情況下的復雜度相同。    
    需要注意的是,算法的復雜度只表示當N值變大時算法的速度變慢的程度,它并不表示算法應用于給定大小的數據集時的實際速度。算法的實際速度與多種因素有關,包括數據集的數據類型以及所用的編程語言、編譯程序和計算機等。換句話說,與復雜度高的算法相比,復雜度低的算法并不具備絕對的優越性。實際上,算法的復雜度的真正意義在于,當N值大于某一數值后,復雜度低的算法就會明顯比復雜度高的算法快。
    為了說明算法的復雜度和算法的實際執行時間之間的關系,表3.2列出了本章所有例子程序的執行時間。本章所有例子程序均在一臺以Linux為操作系統的90MHz奔騰計算機上由GNU C編譯程序編譯,在其它操作系統中,這些例子程序的執行時間與表3.2所列的時間是成比例的。

                 表3. 2  本章所有例子程序的執行時間
---------------------------------------------------------------------------
    例子程序    算  法      2000      4000      6000      8000      10000
---------------------------------------------------------------------------
    例3.1     qsort()      0.02     0.05     0.07     0.11     0,13
    例3.2a    快速排序     0.02     0.07     0.13     0.18     0.20
    例3.2b    歸并排序     0.03     0.08     0.14     0.18     0.26
    例3.2c    基數排序     0.07     0.15     0.23     0.30     0.39
    例3.4     bsearch()    0. 37     0.39     0.39     0.40     0.41
    例3.5     折半查找     0.32     0.34     0.34     0.36     0.36
    例3.6     線性查找     9.67     20.68    28.71    36.31    45. 51
    例3.7     鍵樹查找     0.27     0.28     0.29     0.29     0.30
    例3.8     哈希查找     0.25     0.26     0.28     0.29     0.28
---------------------------------------------------------------------------

 注意:(1)表中所列的時間以秒為單位。(2)表中所列的時間經過統一處理,只包括排序或查找所花費的時間。(3)2000等數值表示數據集的數據量。(4)數據集中的數據是從文件/usr/man/manl/gcc.1(GNUC編譯程序中的一個文件)中隨機提取的詞。(5)在查找算法中,要查找的數據是從文件/usr/man/manl/g++.1(GNUC++編譯程序中的一個文件)中隨機提取的詞。(6)函數qsort()和bseareh()分別是C標準庫函數中用于快速排序算法和折半查找算法的函數,其余例子程序是專門為本章編寫的。
    在閱讀完以上內容后,你應該能初步體會到如何根據不同的情況來選用一種合適的排序或查找算法。在Donald E.Knuth所著的《The Art Of Computer Programming,Volume 3,Sorting and Searching》一書中,作者對排序和查找算法進行了全面的介紹,在該書中你將讀到更多關于復雜度和復雜度理論的內容,并且能見到比本章中所提到的更多的算法。

    公用代碼
    本章中的許多例子程序是可以直接編譯運行的。在這些例子程序中,許多代碼是相同的, 這些相同的代碼將統一在本章的末尾列出。

    3.1  哪一種排序方法最方便?
    答案是C標準庫函數qsort(),理由有以下三點:
    (1)該函數是現成的;    
    (2)該函數是已通過調試的;
    (3)該函數通常是已充分優化過的。
    qsort()函數通常使用快速排序算法,該算法是由C. A.R.Hoare于1962年提出的。以下是qsort()函數的原型:
    void qsort(void *buf,size_t hum,size_t size,
    int(*comp)(const void *ele1,const void *ele2));

    qsort()函數通過一個指針指向一個數組(buf),該數組的元素為用戶定義的數據,數組的元素個數為num,每個元素的字節長度都為size。數組元素的排序是通過調用指針comp所指向的一個函數來實現的,該函數對數組中由ele1和ele2所指向的兩個元素進行比較,并根據前者是小于、等于或大于后者而返回一個小于、等于或大于0的值。   
    例3.1中給出了一個函數sortStrings(),該函數就是通過qsort()函數對一個以NULL指針結束的字符串數組進行排序的。將例3.1所示的代碼和本章結尾的有關代碼一起編譯成一個可執行程序后,就能按字母順序對一個以NULL指針結束的字符串數組進行排序了。

1:#include<stdlib. h>
 2:
 3: /*
 4:  * This routine is used only by sortStrings(), to provide a
 5:  * string comparison {unction to pass to qsort().
 6:  */
 7: static int comp(const void * elel, const void * ele2)
 8: {
 9:    return strcmp( * (const char * * ) ele1,
10:                * (const char * * ) ele2);
11: }
12:
13: / * Sort strings using the library function qsort() * /
14: void sortStrings(const char * array[-'])
15: {
16,       /* First, determine the length of the array * /
17:       int num;
18:
19:      for (num=O; array[num]; num++)
20:
21:      qsort(array, num, sizeof( * array), comp) ;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色欧美片视频在线观看| 久久精品国产亚洲a| 日韩成人午夜精品| 国产成人丝袜美腿| 欧洲在线/亚洲| 精品sm在线观看| 亚洲欧美日韩国产中文在线| 日韩电影免费在线看| 国产精品一区久久久久| 在线观看中文字幕不卡| 久久综合色播五月| 亚洲亚洲精品在线观看| 国产综合色在线视频区| 在线视频国内一区二区| www欧美成人18+| 亚洲国产成人av网| 高清不卡在线观看av| 欧美精品日韩综合在线| 国产精品人人做人人爽人人添| 亚洲观看高清完整版在线观看 | 91精品国产一区二区三区蜜臀| 久久久久青草大香线综合精品| 一区二区三国产精华液| 国产精品一区三区| 欧美一区二视频| 亚洲精品一二三区| 国产宾馆实践打屁股91| 91精品国产综合久久久蜜臀粉嫩 | 国产很黄免费观看久久| 欧美日韩国产三级| 亚洲欧美在线观看| 国产在线观看免费一区| 欧美日韩成人一区二区| 成人欧美一区二区三区黑人麻豆| 久久疯狂做爰流白浆xx| 欧美日韩一区二区三区高清| 亚洲欧洲日韩av| 国产一级精品在线| 91精品国产乱| 性久久久久久久久| 一本久道久久综合中文字幕 | 色婷婷精品大视频在线蜜桃视频| 久久综合国产精品| 久久精品国产久精国产| 欧美另类久久久品| 亚洲制服丝袜av| 色哟哟欧美精品| 国产精品亲子伦对白| 国产一区二区美女诱惑| 日韩欧美国产系列| 青娱乐精品视频| 欧美精品第一页| 亚洲国产视频网站| 欧美影视一区在线| 亚洲欧美国产77777| 成人ar影院免费观看视频| 久久久亚洲高清| 韩日欧美一区二区三区| 日韩欧美一级精品久久| 蜜桃视频在线观看一区二区| 欧美日本一区二区| 午夜日韩在线观看| 在线播放中文字幕一区| 亚洲va韩国va欧美va精品| 精品视频在线免费| 亚洲国产日韩一级| 欧美裸体一区二区三区| 亚洲高清久久久| 欧美日韩日日骚| 丝袜美腿亚洲一区| 欧美一区二区免费视频| 奇米影视一区二区三区小说| 欧美另类一区二区三区| 日韩精品每日更新| 日韩欧美国产小视频| 激情六月婷婷综合| 国产网红主播福利一区二区| 国产成人免费视频网站| 国产精品萝li| 色婷婷av一区二区三区gif | 欧美图区在线视频| 午夜伦欧美伦电影理论片| 欧美一区二区美女| 精品一区二区三区欧美| 精品噜噜噜噜久久久久久久久试看| 久久不见久久见中文字幕免费| 日韩免费福利电影在线观看| 精品无人码麻豆乱码1区2区| 久久久久久久久久久久电影 | 日韩一区在线免费观看| 91国产丝袜在线播放| 亚洲va中文字幕| 欧美成人官网二区| 成人小视频在线观看| 一区二区在线观看av| 欧美美女喷水视频| 国产一区福利在线| 中文字幕人成不卡一区| 精品视频1区2区| 久久国内精品视频| 国产精品成人免费精品自在线观看 | av成人动漫在线观看| 亚洲一级不卡视频| 精品精品欲导航| 成人aa视频在线观看| 亚洲成a人片在线观看中文| 日韩欧美资源站| 国产ts人妖一区二区| 亚洲影院免费观看| 日韩精品最新网址| 99re热这里只有精品视频| 亚洲1区2区3区视频| www国产精品av| 色综合激情五月| 麻豆精品国产91久久久久久| 日本一区二区免费在线| 精品视频999| 国产成人综合在线观看| 亚洲国产精品欧美一二99| 26uuu另类欧美| 日本韩国精品在线| 国产在线精品一区二区| 亚洲综合激情小说| 国产婷婷色一区二区三区四区| 欧美性欧美巨大黑白大战| 国内精品久久久久影院一蜜桃| 亚洲裸体xxx| 26uuu国产日韩综合| 欧美自拍丝袜亚洲| 国产成人一区在线| 日韩电影在线一区二区三区| 国产精品国产三级国产普通话三级 | 国产三级精品视频| 69久久夜色精品国产69蝌蚪网| 国产99久久久国产精品潘金| 日本美女一区二区三区视频| 中文字幕中文字幕在线一区 | 日本中文字幕一区二区有限公司| 国产精品二三区| 精品少妇一区二区三区在线播放 | 中文字幕一区二区在线播放| 日韩欧美一级片| 欧美亚洲综合一区| av在线不卡观看免费观看| 国内精品久久久久影院薰衣草 | 91精品国产一区二区三区香蕉| 99精品国产热久久91蜜凸| 国产在线精品不卡| 奇米色一区二区三区四区| 一区二区三区资源| 国产精品久久久久久亚洲伦| 久久一夜天堂av一区二区三区 | 日本亚洲一区二区| 一区二区三区波多野结衣在线观看| 欧美高清在线精品一区| 欧美tickle裸体挠脚心vk| 欧美精品一卡两卡| 欧美亚洲图片小说| 91无套直看片红桃| 不卡一区在线观看| 国产成人精品免费在线| 黑人巨大精品欧美黑白配亚洲| 日韩激情在线观看| 亚洲午夜精品在线| 亚洲乱码国产乱码精品精的特点| 国产精品私人影院| 国产视频一区二区三区在线观看| 欧美zozo另类异族| 欧美一级欧美三级在线观看 | 久久69国产一区二区蜜臀| 日日摸夜夜添夜夜添亚洲女人| 夜夜嗨av一区二区三区四季av| 国产精品成人一区二区艾草 | 国产成人8x视频一区二区| 黑人巨大精品欧美一区| 久久精品国产秦先生| 久久精品国产色蜜蜜麻豆| 久久精品国产一区二区三区免费看| 丝袜美腿高跟呻吟高潮一区| 视频在线观看一区| 日韩制服丝袜av| 免费在线看成人av| 久久国产视频网| 国产乱码精品一区二区三区五月婷| 韩国v欧美v日本v亚洲v| 国产福利一区二区三区视频在线| 国产成人在线影院 | 中文字幕在线不卡国产视频| 综合精品久久久| 一区二区三区免费网站| 亚洲国产综合在线| 日韩成人免费看| 韩国午夜理伦三级不卡影院| 国产高清不卡一区| 99精品视频一区| 在线精品视频免费播放| 欧美日韩国产一区| 欧美大尺度电影在线| 国产视频一区二区在线| 中文字幕一区二区三区四区|