排序(sort)或分類
所謂排序,就是要整理檔案中的記錄,使之按關鍵字遞增(或遞減)次序排列起來。其確切定義如下:
輸入:n個記錄R1,R2,…,Rn,其相應的關鍵字分別為K1,K2,…,Kn。
輸出:Ril,Ri2,…,Rin,使得Ki1≤Ki2≤…≤Kin。(或Ki1≥Ki2≥…≥Kin)。
1.被排序對象--檔案
被排序的對象--檔案由一組記錄組成。
記錄則由若干個資料項目(或域)組成。其中有一項可用來標識一個記錄,稱為關鍵字項。該資料項目的值稱為關鍵字(Key)。
注意:
在不易產生混淆時,將關鍵字項簡稱為關鍵字。
2.排序運算的依據--關鍵字
用來作排序運算依據的關鍵字,可以是數字類型,也可以是字元類型。
關鍵字的選取應根據問題的要求而定。
【例】在高考成績統計中將每個考生作為一個記錄。每條記錄包含准考證號、姓名、各科的分數和總分數等項內容。若要惟一地標識一個考生的記錄,則必須用"准考證號"作為關鍵字。若要按照考生的總分數排名次,則需用"總分數"作為關鍵字。
排序的穩定性
當待排序記錄的關鍵字均不相同時,排序結果是惟一的,否則排序結果不唯一。
在待排序的檔案中,若存在多個關鍵字相同的記錄,經過排序後這些具有相同關鍵字的記錄之間的相對次序保持不變,該排序方法是穩定的;若具有相同關鍵字的記錄之間的相對次序發生變化,則稱這種排序方法是不穩定的。
注意:
排序演算法的穩定性是針對所有輸入執行個體而言的。即在所有可能的輸入執行個體中,只要有一個執行個體使得演算法不滿足穩定性要求,則該排序演算法就是不穩定的。
排序方法的分類
1.按是否涉及資料的內、外存交換分
在排序過程中,若整個檔案都是放在記憶體中處理,排序時不涉及資料的內、外存交換,則稱之為內部排序(簡稱內排序);反之,若排序過程中要進行資料的內、外存交換,則稱之為外部排序。
注意:
①內排序適用於記錄個數不很多的小檔案
②外排序則適用於記錄個數太多,不能一次將其全部記錄放人記憶體的大檔案。
2.按策略劃分內部排序方法
可以分為五類:插入排序、選擇排序、交換排序、歸併排序和分配排序。
排序演算法分析
1.排序演算法的基本操作
大多數排序演算法都有兩個基本的操作:
(1)比較兩個關鍵字的大小;
(2)改變指向記錄的指標或移動記錄本身。
注意:
第(2)種基本操作的實現依賴於待排序記錄的儲存方式。
2.待排檔案的常用儲存方式
(1)以順序表(或直接用向量)作為儲存結構
排序過程:對記錄本身進行物理重排(即通過關鍵字之間的比較判定,將記錄移到合適的位置)
(2)以鏈表作為儲存結構
排序過程:無須移動記錄,僅需修改指標。通常將這類排序稱為鏈表(或鏈式)排序;
(3)用順序的方式儲存待排序的記錄,但同時建立一個輔助表(如包括關鍵字和指向記錄位置的指標組成的索引表)
排序過程:只需對輔助表的表目進行物理重排(即只移動輔助表的表目,而不移動記錄本身)。適用於難於在鏈表上實現,仍需避免排序過程中移動記錄的排序方法。
3.排序演算法效能評價
(1)評價排序演算法好壞的標準
評價排序演算法好壞的標準主要有兩條:
①執行時間和所需的輔助空間
②演算法本身的複雜程度
(2)排序演算法的空間複雜度
若排序演算法所需的輔助空間並不依賴於問題的規模n,即輔助空間是O(1),則稱之為就地排序(In-PlaceSou)。
非就地排序一般要求的輔助空間為O(n)。
(3)排序演算法的時間開銷
大多數排序演算法的時間開銷主要是關鍵字之間的比較和記錄的移動。有的排序演算法其執行時間不僅依賴於問題的規模,還取決於輸入執行個體中資料的狀態。
檔案的順序儲存結構表示
#define n l00 //假設的檔案長度,即待排序的記錄數目
typedef int KeyType; //假設的關鍵字類型
typedef struct{ //記錄類型
KeyType key; //關鍵字項
InfoType otherinfo;//其它資料項目,類型InfoType依賴於具體應用而定義
}RecType;
typedef RecType SeqList[n+1];//SeqList為順序表類型,表中第0個單元一般用作哨兵
注意:
若關鍵字類型沒有比較算符,則可事先定義宏或函數來表示比較運算。
【例】關鍵字為字串時,可定義宏"#define LT(a,b)(Stromp((a),(b))<0)"。那麼演算法中"a<b"可用"LT(a,b)"取代。若使用C++,則定義重載的算符"<"更為方便。