【筆記】樹形選擇排序
樹形選擇排序:又稱為錦標賽排序,是一種按照錦標賽的思想進行選擇排序的方法。
基本演算法思想:首先對n個記錄的關鍵字進行兩兩比較,然後在其中[
n2 \frac {n}{2}]個較小者之間再進行兩兩比較,如此重複,直至選出最小關鍵字的記錄為止。這個過程可用一棵有n個葉子結點的完全二叉樹表示。
如下圖所從8個關鍵字中選擇出最小關鍵字的過程。8個葉子結點中一次存放排序之前的8個關鍵字,每個非終端結點中的關鍵字均等於其左、右孩子結點中較小的關鍵字,則根結點中的關鍵字即為葉子結點中的最小關鍵字。在輸出最小關鍵字之後,根據關係的可傳遞性,預選出次小關鍵字,僅需將葉子結點中的最小關鍵字改為“最大值”,然後從該葉子結點開始,和其左(或右)兄弟的關鍵字進行比較,修改從葉子結點到根的路徑上各結點的關鍵字,則根結點的關鍵字即為次小關鍵字。同理,依次可選出從小到大的所有關鍵字。
由於含有n個葉子結點的完全二叉樹的深度為[
log_2 n
]+1,則在樹形選擇排序中,除了最小關鍵字之外,每選擇一個次小關鍵字僅需進行[log_2 n
]次比較,因此它的時間複雜度為O(nlogn)
。但是這種排序方法尚有輔助儲存空間較多、和最大值進行多餘的比較等缺點。為了彌補可以使用另一種形式的選擇排序——堆排序。
- 型別定義
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的型別 */
typedef int KeyType; /* 定義關鍵字型別為整型 */
typedef struct
{
KeyType key; /* 關鍵字項 */
InfoType otherinfo; /* 其它資料項,具體型別在主程中定義 */
}RedType; /* 記錄型別 */
typedef struct
{
RedType r[MAXSIZE+1]; /* r[0]閒置或用作哨兵單元 */
int length; /* 順序表長度 */
}SqList; /* 順序表型別 */
- 樹形選擇排序函式
void TreeSort(SqList *L)
{ /* 樹形選擇排序 */
int i,j,j1,k,k1,l,n=(*L).length;
RedType *t;
l=(int)ceil(log(n)/log(2))+1; /* 完全二叉樹的層數 */
k=(int)pow(2,l)-1; /* l層完全二叉樹的結點總數 */
k1=(int)pow(2,l-1)-1; /* l-1層完全二叉樹的結點總數 */
t=(RedType*)malloc(k*sizeof(RedType)); /* 二叉樹採用順序儲存結構 */
for(i=1;i<=n;i++) /* 將L.r賦給葉子結點 */
t[k1+i-1]=(*L).r[i];
for(i=k1+n;i<k;i++) /* 給多餘的葉子的關鍵字賦無窮大 */
t[i].key=INT_MAX;
j1=k1;
j=k;
while(j1)
{ /* 給非葉子結點賦值 */
for(i=j1;i<j;i+=2)
t[i].key<t[i+1].key?(t[(i+1)/2-1]=t[i]):(t[(i+1)/2-1]=t[i+1]);
j=j1;
j1=(j1-1)/2;
}
for(i=0;i<n;i++)
{
(*L).r[i+1]=t[0]; /* 將當前最小值賦給L.r[i] */
j1=0;
for(j=1;j<l;j++) /* 沿樹根找結點t[0]在葉子中的序號j1 */
t[2*j1+1].key==t[j1].key?(j1=2*j1+1):(j1=2*j1+2);
t[j1].key=INT_MAX;
while(j1)
{
j1=(j1+1)/2-1; /* 序號為j1的結點的雙親結點序號 */
t[2*j1+1].key<=t[2*j1+2].key?(t[j1]=t[2*j1+1]):(t[j1]=t[2*j1+2]);
}
}
free(t);
}
- 主程式
#include<limits.h> /* INT_MAX等 */
#define N 8
void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
TreeSort(&l);
printf("排序後:\n");
print(l);
}
- 測試結果
相關文章
- treeSelect樹形選擇器使用
- [筆記]樹形dp筆記
- 基礎排序(冒泡、選擇、插入)學習筆記排序筆記
- jeecgboot-vue3筆記(九)——treeSelect樹形選擇元件的使用(非同步載入)bootVue筆記元件非同步
- 資料結構學習筆記-簡單選擇排序資料結構筆記排序
- C++ Qt開發:TreeWidget 樹形選擇元件C++QT元件
- 選擇排序排序
- 選擇排序和快速排序排序
- 選擇排序法排序
- 01選擇排序排序
- Java 選擇排序Java排序
- js選擇排序JS排序
- 【CTO變形記】驅動力的選擇
- 桶排序 選擇,插入排序排序
- 氣泡排序與選擇排序排序
- 排序演算法:選擇排序排序演算法
- 排序演算法__選擇排序排序演算法
- 選擇排序和氣泡排序排序
- 簡單選擇排序排序
- 陣列選擇排序陣列排序
- C# 選擇排序C#排序
- CSS筆記——屬性選擇器CSS筆記
- 經典排序之選擇排序(Java)排序Java
- 排序——選擇排序小練習(二)排序
- 排序——選擇排序小練習(一)排序
- 樹形問題選講
- PHP 排序演算法之選擇排序PHP排序演算法
- Python排序演算法之 選擇排序Python排序演算法
- 排序演算法入門:選擇排序排序演算法
- 氣泡排序和選擇排序詳解排序
- 排序演算法之「選擇排序(SelectionSort) 」排序演算法
- 圖解選擇排序與插入排序圖解排序
- 氣泡排序和選擇排序流程圖排序流程圖
- 選擇排序(python)實現排序Python
- 排序演算法 - 氣泡排序和選擇排序排序演算法
- Jquery基礎筆記二(選擇器)jQuery筆記
- css 選擇器及權重筆記CSS筆記
- CSS 小結筆記之選擇器CSS筆記
- 手寫演算法並記住它:選擇排序演算法排序