插入排序-2-路插入排序

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;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章