內部排序->選擇排序->樹形選擇排序

來源:互聯網
上載者:User

標籤:下標   最小值   輸入   amp      樹的定義   red   while   排序演算法   

文字描述

  樹形選擇排序又稱錦標賽排序; 比如,在8個運動員中決出前3名至多需要11場比賽, 而不是7+6+5=18場比賽(它的前提是甲勝乙,乙勝丙,則甲必能勝丙)

  首先對n個記錄的關鍵字進行兩兩比較,然後在(n/2)個較小者之間再進行兩兩比較,直至選出最小關鍵字的記錄為止,這個過程可用一顆有n個葉子結點的完全二叉樹表示。關於完全二叉樹的定義和與本排序演算法用到的性質見附錄1

 

演算法分析

   由於含n個葉子結點的完全二叉樹的深度為[log2n]+1, 則在樹形選擇排序中,除了最小關鍵字外,每選擇一個次小關鍵字僅需進行log2n次比較,因此它的時間複雜度為nlogn.。但是它需要的輔助空間為2*n-1。而且它在選擇過程中,和"最大值"進行了多餘的比較。 另外,該演算法是不穩定的。

代碼實現

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <math.h>  4 /*  5  * double log2(double x);    以2為底的對數  6  * double ceil(double x);    取上整  7  * double floor(double x);    取下整  8  * double fabs(double x);    取絕對值  9  */ 10  11 #define DEBUG 12  13 #define EQ(a, b) ((a) == (b)) 14 #define LT(a, b) ((a) <  (b)) 15 #define LQ(a, b) ((a) <= (b)) 16  17 #define MAXSIZE  100 18 #define INF         1000000 19 typedef int KeyType; 20 typedef char InfoType; 21 typedef struct{ 22     KeyType key; 23     InfoType otherinfo; 24 }RedType; 25  26 typedef struct{ 27     RedType r[MAXSIZE+1]; 28     int length; 29 }SqList; 30  31 void PrintList(SqList L){ 32     int i = 0; 33     printf("下標值:"); 34     for(i=0; i<=L.length; i++){ 35         printf("[%d] ", i); 36     } 37     printf("\n關鍵字:"); 38     for(i=0; i<=L.length; i++){ 39         if(EQ(L.r[i].key, INF)){ 40             printf(" %-3c", ‘-‘); 41         }else{ 42             printf(" %-3d", L.r[i].key); 43         } 44     } 45     printf("\n其他值:"); 46     for(i=0; i<=L.length; i++){ 47         printf(" %-3c", L.r[i].otherinfo); 48     } 49     printf("\n\n"); 50     return ; 51 } 52  53 /*樹形選擇排序演算法*/ 54 void TreeSelectSort(SqList *L) 55 { 56     //為實現該排序所需的輔助樹 57     SqList tree; 58     //輔助樹的大小 59     tree.length = L->length-1 + L->length; 60  61     tree.r[0].otherinfo = ‘0‘; 62     int i = 0, low = 1; 63     //由後向前填充此樹的葉子結點 64     for(i=0; i<L->length; i++){ 65         tree.r[tree.length-i] = L->r[L->length-i]; 66     } 67     //由後向前填充此樹的非葉子結點 68     for(i=(tree.length-L->length); i>=1; i--){ 69         tree.r[i] = (LT(tree.r[2*i].key, tree.r[2*i+1].key)?tree.r[2*i]:tree.r[2*i+1]); 70     } 71     //紀錄當前輔助樹的最小結點 72     RedType minred; 73     //記錄最小結點在葉子結點中的下標值 74     int minindex = 0; 75     while(low <= L->length){ 76         minred = tree.r[1]; 77 #ifdef DEBUG 78         printf("第%d趟樹形選擇排序後,輸出當前數最小值%d, %c\n", low, minred.key, minred.otherinfo); 79         PrintList(tree); 80 #endif 81         //不斷移走最小結點 82         L->r[low++] = minred; 83         minindex = tree.length; 84         //找到最小值在輔助樹葉子結點中的下標值 85         for(minindex=tree.length; (minindex>(tree.length-L->length)); minindex--){ 86             if(EQ(tree.r[minindex].key, minred.key) && EQ(tree.r[minindex].otherinfo, minred.otherinfo)){ 87                 break; 88             } 89         } 90         //設定一個最大值標誌,INF表示無窮大 91         tree.r[minindex].key = INF; 92         //重新調整此輔助樹,使根結點關鍵字值最小 93         for(i=(minindex/2); i>=1; i/=2){ 94             tree.r[i] = (LT(tree.r[2*i].key, tree.r[2*i+1].key)?tree.r[2*i]:tree.r[2*i+1]); 95         } 96     } 97 #ifdef DEBUG 98     printf("按照樹形選擇排序後的原順序表:\n"); 99     PrintList(*L);100 #endif101 }102 103 int  main(int argc, char *argv[])104 {105     if(argc < 2){106         return -1;107     }108     SqList L;109     int i = 0;110     for(i=1; i<argc; i++){111         if(i>MAXSIZE)112             break;113         L.r[i].key = atoi(argv[i]);114         L.r[i].otherinfo = ‘a‘+i-1;115     }116     L.length = (i-1);117     L.r[0].key = 0;118     L.r[0].otherinfo = ‘0‘;119     printf("輸入資料:\n");120     PrintList(L);121     //對順序表L作樹形選擇排序122     TreeSelectSort(&L);123     return 0;124 }
樹形選擇排序

 

運行

 

 

附錄1 完全二叉樹

定義:設二叉樹深度為h,除第h層外,其他各層(1 ~ h-1)的結點數都達到最大個數,第h層所有的結點都集中在最左邊,這就是完全二叉樹。

性質:

1] 結點i (i>1)的雙親結點為i/2

2] 結點i的左孩子結點為2*i, 右孩子結點為2*i+1

3] 葉子結點數n0, 度為2(有左、右孩子結點)的結點數n2, 則n0 = n2+1

 

性質3]證明:

  設n1為二叉樹中度為1的結點數。因為二叉樹中所有結點數的度均不大於2。所以二叉樹的結點數n = n0 + n1 +n2 -- (1)。

  又除根結點外,其餘結點都有一個分支進入,設B為分支總數,則n=B+1。由於這些分支是由度為1或2的結點射出的,所以又有B=n1+2*n2,於是得n = B+1 = n1+2*n2+1 – (2)。

  由(1)和(2)知, n0 = n2 +1

內部排序->選擇排序->樹形選擇排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.