先看排序思路:
直接插入排序是一種最簡單的排序方法,它的基本操作是將乙個記錄插入到已排好序的有序表中,從而得到乙個新的、記錄數增1的有序表。思路確實很簡單,以乙個遞增的記錄序列為例:每每插入乙個記錄,我們都需將被插入的記錄和序列中的每乙個記錄相比較來確定插入位置,然後插入。僅此而已。但是演算法實現的過程很是痛苦。好在書本給出範例供學習參考。來自《資料結構》-----嚴蔚敏、吳偉民 編著
範例中主要有兩個困難,乙個是查詢過程中可能會出現的陣列越界問題;另乙個是直接在原有有序表上進行排序,而不是搞兩個分開的表。我個人認為把兩個表分開會更直觀一些。不過直觀歸直觀,還是最簡潔的演算法最有效率。
我將對演算法各個過程的理解寫到了注釋中,加上本人的注釋後有些許凌亂,不過個人感覺還是很通俗易懂的。看不懂就說"hhhc"[doge]。演算法如下:
#define maxsize 20
typedef
int keytype;
//方便起見,將關鍵字型別設定為整數
typedef
struct
redtype;
//redtype 表示記錄型別
typedef
struct
sqlist;
//sqlist 表示順序表型別
/*************結構體結束,正事兒開始*************/
void
insertsort
(sqlist &l)
//for
//此時r[j+1]已經後移到r[j+2],r[j+1]的位置算是空出來了,這就是插入r[i]的地方
l.r[j+1]
= l.r[0]
;//把r[i]的備份r[0]插入空位,完成排序
}//if
}//for
}//void insertsort()
//到演算法寫完才想到 還有個陣列下標越界的問題沒考慮,不過沒關係。該問題可能會出現在第 2 個 「for迴圈」 中
//假如插入的r[i]是目前序列裡最小的,那麼j就會一直減一直減,總有j減少的0的時候,不過這個時候就會跳出循
//環了,因為lt(a,b)表示的是 a
不得不說,寫出這種東西真是不簡單。不過還不算完,還有強化版本…
直接插入排序演算法簡便,且容易實現。當待排序記錄的數量n很小時,這是一種很小的排序方法。但是通常待排序序列中的記錄數量n很大,不宜採用直接插入排序。由此要改進,在其基礎上,從減少「比較」和「移動」的次數著眼。
利用折半查詢法查詢插入座標的演算法如下:
void
binsertsort
(sqlist& l)
//while
for(j=i-2;
lt(l.r[0]
.key,l.r[j]
);j--
) l.r[j+1]
= l.r[j]
; l.r[high+1]
= l.r[0]
;//插入 ,插入到哪個地方是個難點
}}
講真,有了插入排序演算法的基礎再看這個演算法的話,著實不那麼苦難了。不過還是有兩點需要關注一下,乙個是 high 的初始值,另乙個是插入的位置怎麼計算。
① high 初始值:
這裡遵循直接插入排序的特點,所被插入的序列是由之前插入的記錄構成。而且從原記錄表中取記錄的順序是從前往後取。因此 high 不能一開始就取到整個序列的最後方。
②插入位置的計算:
折半查詢法的各種操作沒有改變,這就需要折半查詢法的基礎了:在折半查詢法中,若查詢不到記錄,則查詢區間一定為-1。我們可以舉乙個例子來幫助我們尋找插入位置:
記錄38
4965
97位置12
34
資料結構 直接插入排序
直接插入排序 include include typedef struct int elem int length sqlist void initsqlist sqlist l int i printf 請輸入元素個數 scanf d l length l elem int malloc size...
資料結構 直接插入排序
直接插入排序 將待插入子串行元素逐步插入到有序序列的執行過程。設有一待排序序列s 其中是有序的,是無序的,要把後面無需的元素,乙個乙個的插入到前面有序的集合中去。如下面的序列可以分為兩個子串行 和 初始序列 75 88 68 92 88 62 77 96 80 72 第一次排序 75 88 68 9...
資料結構 直接插入排序
將乙個記錄插入到已排好序的序列中,從而得到乙個新的有序序列 將序列的第乙個資料看成是乙個有序的子串行,然後從第二個記錄逐個向該有序的子串行進行有序的插入,直至整個序列有序 可以選擇不同的方法在已經排好序資料表中尋找插入位置。根據查詢方法不同,有多種插入排序方法,下面要介紹的是直接插入排序。設待排序的...