2-路插入排序
一、定義
2-路插入排序是在折半插入排序的基礎上再改進,其目的是減少排序過程中移動記錄的次數,但爲此要付出n個記錄的輔助空間。
二、具體實現
另設一個同類型的數組d,先將list[0]複製給d[0],並將d[0]看成是排好序的序列中處於中間位置的記錄,然後從list中第二個記錄起依次插入到d[0]之前或之後的有序序列中。先將待插入記錄和d[0]進行比較,若大於d[0],則插入d[0]後的有序表中,反之,則插入d[0]之前的有序表中。可以將d看成是一個循環量,並設置first和final指針分別指向有序表中第一個和最後一個記錄的位置。
移動記錄約爲你n^2 / 8,因此,2-路插入排序只能減少移動記錄次數,而不能絕對避免移動記錄。並且,當list[1]是待排序記錄中最大或最小的記錄時,2-路插入排序就完全失去它的優越性。
void twoinsert_sort(ElementType list[],int n){
int i,j,first,final;
ElementType *d = (ElementType *)malloc(sizeof(ElementType) * n);
if(d != NULL){
d[0] = list[0];//以d[0]作爲界限,位置一直不變,d看作循環向量
first = final = 0;
for(i = 1; i < n ;i++){
//插入右邊區域
if(list[i] >= d[0]){
if(list[i] >= d[final])//插入值的大於最大值
d[++final] = list[i];
else{
//插入值位於最大值和中間值之間,向後移
for(j = final;j > 0 && d[j] >= list[i];j--) d[j + 1] = d[j];
d[j] = list[i];
final++;
}
}else{//插入左邊區域
//小於當前最小
if(list[i] <= d[first]){
first = (n + first - 1) % n;
d[first] = list[i];
}else{
//插入值位於最小值和中間值之間,向前移
first--; //先--,確定first位置
for(j = first + 1; j < n && d[j] <= list[i] ;j++) d[j - 1] = d[j];
d[j - 1] = list[i];
}
}
}
//複製
for(i = 0; i < n ;i++){
list[i] = d[(first++) % n];
}
//釋放輔助空間
free(d);
d = NULL;
}
}