插入排序-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;
	}
}

Guess you like

Origin blog.csdn.net/psl1234554321/article/details/106183290