C 資料結構與演算法揭秘19

2022-02-09 16:57:47 字數 2697 閱讀 7195

這節,我們介紹基數排序和歸併排序。

一、基數排序

基數排序(radix sort)的設計思想與前面介紹的各種排序方法完全不同。前面介紹的排序方法主要是通過關鍵碼的比較和記錄的移動這兩種操作來實現排序的,而基數排序不需要進行關鍵碼的比較和記錄的移動。基數排序是一種借助於多關鍵碼排序的思想,是將單關鍵碼按基數分成多關鍵碼進行排序的方法,是一種分配排序。

下面用乙個具體的例子來說明多關鍵碼排序的思想。

一副撲克牌有 52 張牌,可按花色和面值進行分類,其大小關係如下:

花色:梅花《方塊《紅心《黑心

面值:2<3<4<5<6<7<8<9<10其中,k1稱為最主位關鍵碼,kd稱為最次位關鍵碼。

多關鍵碼排序方法按照從最主位關鍵碼到最次位關鍵碼或從最次位關鍵碼到最主位關鍵碼的順序進行排序,分為兩種排序方法:

(1)最高位優先法(msd法) 。先按k1排序,將序列分成若干子串行,每個子串行中的記錄具有相同的k1值;再按k2排序,將每個子串行分成更小的子串行;然後,對後面的關鍵碼繼續同樣的排序分成更小的子串行,直到按kd排序分組分成最小的子串行後,最後將各個子串行連線起來,便可得到乙個有序的序列。前面介紹的撲克牌先按花色再按面值進行排序的方法就是msd法。

(2)最次位優先法(lsd法) 。先按kd排序,將序列分成若干子串行,每個子串行中的記錄具有相同的kd值; 再按kd-1排序, 將每個子串行分成更小的子串行;然後,對後面的關鍵碼繼續同樣的排序分成更小的子串行,直到按k1排序分組分成最小的子串行後,最後將各個子串行連線起來,便可得到乙個有序的序列。前面介紹的撲克牌先按面值再花色按進行排序的方法就是lsd法。

基數的源**如下:

//

基數排序的方法

public

int radixsort(int arraytosort, int digit,int

len)

for (int m = 1; m < 10; m++)

//輸出的結果

for (int n = arraytosort.length - 1; n >= 0; n--)

//拷貝排序的陣列

for (int p = 0; p < arraytosort.length; p++)

}return

arraytosort;

}//雙層的迴圈 時間的複雜度是o(n2)

如圖所示:

基數排序是穩定的排序,時間的複雜度是o(n2).

二、歸併排序

歸併排序(merge sort)主要是二路歸併排序。二路歸併排序的基本思想是:將兩個有序表合併為乙個有序表。

假設順序表 sqlist 中的 n 個記錄為 n 個長度為1的有序表,從第1個有序表開始,把相鄰的兩個有序錶兩兩進行合併成乙個有序表,得到 n/2 個長度為2的有序表。如此重複,最後得到乙個長度為 n 的有序表。

一趟二路歸併排序演算法的實現如下所示, 演算法中記錄的比較代表記錄關鍵碼的比較,順序表中只存放了記錄的關鍵碼:

對於n個記錄的順序表,將這n個記錄看作葉子結點,若將兩兩歸併生成的子表看作它們的父結點, 則歸併過程對應於由葉子結點向根結點生成一棵二叉樹的過程。所以,歸併趟數約等於二叉樹的高度減1,即log2n,每趟歸併排序記錄關鍵碼比較的次數都約為n/2,記錄移動的次數為2n(臨時順序表的記錄複製到原順序表中記錄的移動次數為n) 。 因此, 二路歸併排序的時間複雜度為o (nlog2n) 。

而二路歸併排序使用了n個臨時記憶體單元存放記錄,所以,二路歸併排序演算法的空間複雜度為o(n) 。歸併排序,如圖所示:

一趟二路歸併排序演算法的實現如下所示, 演算法中記錄的比較代表記錄關鍵碼的比較,順序表中只存放了記錄的關鍵碼,相應的源**如下:

public

void merge(seqlist sqlist, int

len)

//第2個有序表記錄的關鍵碼小於第1個有序表記錄的關鍵碼

else

} //第1個有序表中還有記錄沒有排序完

while (i <=h1)

//第2個有序表中還有記錄沒有排序完

while (j <=h2)

l1 = h2 + 1

; }

i =l1;

//原順序表中還有記錄沒有排序完

while (i

//臨時順序表中的記錄複製到原順序表,使原順序表中的記錄有序

for (i = 0; i < sqlist.getlength(); ++i)

} 二路歸併排序演算法的實現如下:

public

void mergesort(seqlistsqlist)

}

對於n個記錄的順序表,將這n個記錄看作葉子結點,若將兩兩歸併生成的子表看作它們的父結點, 則歸併過程對應於由葉子結點向根結點生成一棵二叉樹的過程。所以,歸併趟數約等於二叉樹的高度減1,即log2n,每趟歸併排序記錄關鍵碼比較的次數都約為n/2,記錄移動的次數為2n(臨時順序表的記錄複製到原順序表中記錄的移動次數為n) 。 因此, 二路歸併排序的時間複雜度為o (nlog2n)。而二路歸併排序使用了n個臨時記憶體單元存放記錄,所以,二路歸併排序演算法的空間複雜度為o(n) 。

c#資料結構,就此結束了,這是我的一點總結。

資料結構與演算法 揭秘

字面意思就是研究資料的一種方法,就是研究資料在程式中組織的一種方法。資料結構就是,元素與元素有一種或者多種關係的集合,在軟體界有一種比較普片的公式就是程式 資料結構 演算法。1 集合 set 和數學的集合一樣,具有唯一性,確定性,無序性。2 線性結構 典型的資料庫二維表,一對一的關係。3 樹形結構 ...

C 資料結構與演算法揭秘一

這裡,我們 來說一說c 的資料結構了。什麼是資料結構。資料結構,字面意思就是研究資料的方法,就是研究資料如何在程式中組織的一種方法。資料結構就是相互之間存在一種或多種特定關係的資料元素的集合。程式界有一點很經典的話,程式設計 資料結構 演算法。用源 來體現,資料結構,就是程式設計。他有哪些具體的關係...

C 資料結構與演算法揭秘13

這節,我們來看看一下什麼了,來看看圖的遍歷吧!首先,搞清楚,圖的遍歷的基本的含義了。圖的遍歷是指從圖中的某個頂點出發,按照某種順序訪問圖中的每個頂點,使每個頂點被訪問一次且僅一次。圖的遍歷與樹的遍歷操作功能相似。圖的遍歷是圖的一種基本操作,並且圖的許多其他操作都是建立在遍歷操作的基礎之上的。遍歷示意...