直接
插入排序
(straight insertion sort)是一種最簡單的排序方法,其基本操作是將一條記錄插入到已排好的有序表中,從而得到乙個新的、記錄數量增1的有序表
在日常生活中,經常碰到這樣一類排序問題:把新的資料插入到已經排好的資料列中。例如:一組從小到大排好順序的資料列,通常稱之為有序列,我們用序號1,2,3,…表示資料的位置,欲把乙個新的資料8插入到上述序列中。
完成這個工作的步驟:
①確定資料「8」在原有序列中應該占有的位置序號。資料「8」所處的位置應滿足小於或等於該位置右邊所有的資料,大於其左邊位置上所有的資料。
②將這個位置空出來,將資料「8」插進去。
直接插入排序(straight insertion sort)的做法是:
每次從無序表中取出第乙個元素,把它插入到有序表的合適位置,使有序表仍然有序。
第一趟比較前兩個數,然後把第二個數按大小插入到有序表中; 第二趟把第三個資料與前兩個數從後向前掃瞄,把第三個數按大小插入到有序表中;依次進行下去,進行了(n-1)趟掃瞄以後就完成了整個排序過程。
直接插入排序是由兩層巢狀迴圈組成的。外層迴圈標識並決定待比較的數值。內層迴圈為待比較數值確定其最終位置。直接插入排序是將待比較的數值與它的前乙個數值進行比較,所以外層迴圈是從第二個數值開始的。當前一數值比待比較數值大的情況下繼續迴圈比較,直到找到比待比較數值小的並將待比較數值置入其後一位置,結束該次迴圈。
每一趟將乙個待排序的記錄,按其關鍵字的大小插入到已經排好序的一組記錄的適當位置上,直到所有待排序記錄全部插入為止。
待排序記錄 r1,r2,… ,rn–1, rn
第一步:r1
第二步:(r1 ), r2
第三步:(r1 , r2), r3
第 j 步:(r1,r2,… ,rj–1), rj
第 n 步: (r1,r2,… ,rn–1), rn.
例:j=5
比較次數:dj+1 移動次數: dj+2
3.1 演算法描述
一般來說,插入排序都採用in-place在陣列上實現。具體演算法描述如下:
最佳情況:t(n) = o(n)
最壞情況:t(n) = o(n2)
平均情況:t(n) = o(n2)
1.簡單方法
首先在當前有序區r[1..i-1]中查詢r[i]的正確插入位置k(1≤k≤i-1);然後將r[k..i-1]中的記錄均後移乙個位置,騰出k位置上的空間插入r[i]。
注意:若r[i]的關鍵字大於等於r[1..i-1]中所有記錄的關鍵字,則r[i]就是插入原位置。
2.改進的方法
一種查詢比較操作和記錄移動操作交替地進行的方法。具體做法:
將待插入記錄r[i]的關鍵字從右向左依次與有序區中記錄r[j](j=i-1,i-2,…,1)的關鍵字進行比較:
① 若r[j]的關鍵字大於r[i]的關鍵字,則將r[j]後移乙個位置;
②若r[j]的關鍵字小於或等於r[i]的關鍵字,則查詢過程結束,j+1即為r[i]的插入位置。
關鍵字比r[i]的關鍵字大的記錄均已後移,所以j+1的位置已經騰空,只要將r[i]直接插入此位置即可完成一趟直接插入排序。
演算法中引進的附加記錄r[0]稱監視哨或哨兵(sentinel)。
哨兵有兩個作用:
① 進入查詢(插入位置)迴圈之前,它儲存了r[i]的副本,使不致於因記錄後移而丟失r[i]的內容;
② 它的主要作用是:在查詢迴圈中"監視"下標變數j是否越界。一旦越界(即j=0),因為r[0].可以和自己比較,迴圈判定條件不成立使得查詢迴圈結束,從而避免了在該迴圈內的每一次均要檢測j是否越界(即省略了迴圈判定條件"j>=1")。
注意:① 實際上,一切為簡化邊界條件而引入的附加結點(元素)均可稱為哨兵。
【例】單鏈表中的頭結點實際上是乙個哨兵
② 引入哨兵後使得測試查詢迴圈條件的時間大約減少了一半,所以對於記錄數較大的檔案節約的時間就相當可觀。對於類似於排序這樣使用頻率非常高的演算法,要盡可能地減少其執行時間。所以不能把上述演算法中的哨兵視為雕蟲小技,而應該深刻理解並掌握這種技巧。
例:原有序表:(9 15 23 28 37) 20
找插入位置 : (9 15 ^ 23 28 37) 20
新有序表: (9 15 20 23 28 37)
設待排序的檔案有8個記錄,其關鍵字分別為:49,38,65,97,76,13,27,49。為了區別兩個相同的關鍵字49,後乙個49的下方加了一下劃線以示區別。其排序過程見 [2]
#includeusing namespace std;
int main()
; int k=sizeof(a)/sizeof(a[0]);
int i,j;
for(i=1;i=0 && a[j]>temp;j--)
a[j+1]=temp;//此處就是a[j+1]=temp;}}
for(int f=0;f
return 0;
}
資料結構 直接插入排序
直接插入排序 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...
資料結構 直接插入排序
將乙個記錄插入到已排好序的序列中,從而得到乙個新的有序序列 將序列的第乙個資料看成是乙個有序的子串行,然後從第二個記錄逐個向該有序的子串行進行有序的插入,直至整個序列有序 可以選擇不同的方法在已經排好序資料表中尋找插入位置。根據查詢方法不同,有多種插入排序方法,下面要介紹的是直接插入排序。設待排序的...