二分插入法

二分插入法每次看都无法一次理解清楚,在这里做一次笔记加深下印象。

一、Java代码如下所示:

 

public static void main(String[] args) {
		int [] values = new int[]{3,8,7,6,1,9,12,2,5,11};
		for(int i = 0 ; i < values.length ; i++){
			System.err.print(values[i] + ",");
		}
		System.err.println();
		sort(values);
		System.err.println();
		for(int i = 0 ; i< values.length; i++){
			System.err.print(values[i] + ",");
		}
	}
	public static void sort(int []  values){
		for(int i = 0 ;i < values.length ; i++)       //步骤1
			int now =  values[i];
			int left = 0;
			int right = i -1;
			int center = 0;
			while(left <= right){                //步骤2
				center = (left + right)/2;
				if(now < values[center]){    //步骤2.1
					right = center -1;
				}else{                       //步骤2.2
					 left = center + 1;
				}
			}
			for(int j = i-1 ;j >= left ; j--){   //步骤4  4.1  4.2
				 values[j+1] = values[j];
			}
			if(left != i){                       //步骤5 5.1  5.2
				 values[left] = now;
			}
		}
	}

 输出结果:

 

 

3,8,7,6,1,9,12,2,5,11,

1,2,3,5,6,7,8,9,11,12,

 

二、简单举例说一下当I=4时代码执行过程 ,详细过程如下图所示:

 

在i = 0、1、2、3执行完以后,values的顺序就变成如下列表:

        3, 6, 7, 8, 1, 9, 12, 2, 5, 11

 

此时当i=4初进循环时:

         now = 1 ; left = 0 ; right = 3 ; center = 0;

 

left (1) <= right (3) 进入while循环:

        center(1) = (left(0) + right(3))/2;

 

now(1) < values[center] (6)进入if:

       right(2) = right(3) - 1;

 

left (1) <= right (2)进入while循环:

       center(1) = (left(0) + right(2))/2;

 

now(1) < values[center] (6)进入if:

      right(1) = right(2) - 1;

 

left (1) <= right (1)进入while循环:

       center(0) = (left(0) + right(1))/2;

 

now(1) < values[center] (3)进入if:

        right(0) = right(1) - 1;

 

left (0) <= right (0)进入while循环:

        center(0) = (left(0) + right(1))/2;

 

now(1) < values[center] (3)进入if:

         right(-1) = right(0) - 1;

 

left (0) <= right (-1)跳出while循环:

        center = 0 ; left = 0 ; right=-1; now = 1; 

 

j(3)=i(4)-1 >= left(0) 进入For循环:

       values[j(3)+1] = values[j(3)];

       valus = 3, 6, 7, 8, 8, 9, 12, 2, 5, 11;

 

j(2)=i(4)-1-1 >= left(0) 进入For循环:

       values[j(2)+1] = values[j(2)];

       valus = 3, 6, 7, 7, 8, 9, 12, 2, 5, 11;

 

j(1)=i(4)-1-1-1 >= left(0) 进入For循环:

       values[j(1)+1] = values[j(1)];

       valus = 3, 6, 6, 7, 8, 9, 12, 2, 5, 11;

 

j(0)=i(4)-1-1-1-1 >= left(0) 进入For循环:

       values[j(0)+1] = values[j(0)];

       valus = 3, 3, 6, 7, 8, 9, 12, 2, 5, 11;

 

i(4) != left(0) 进入if:

       now=1 一直没变;

      values[left(0)] =now(1)

      valus = 1, 3, 6, 7, 8, 9, 12, 2, 5, 11

 

 接下来进入当I=5的循环,过程同上。

 

 

 

三、执行流程分析说明:

 

1、对排序数组values进行从索引0进行递增循环,初入循环始终将左索引(left)设置为0,右索引(right)设置为当前索引向左移一位(i-1),并将当前索引(i)对应数组的值赋值给循环内局部变量now进行备份。

 

2、循环使用左索引(left)与右索引(right)进行比较,如果左索引(left)小于或等于右索引(right)时,取出左右索引之和的中间值索引(center)在values数组中的值(values[center])与当前索引(i)在values数组中的值(now<--values[i]-->)进行比较。

 

      2.1、如果中间索引值(values[center])大于当前索引值(now<--values[i]-->)时,将得到的中间索引(center)向左移动一位重新计算出右索引(right=center-1),继续第2步进行左右索引比较、中间索引值与当前索引值比较。

 

      2.2、如果中间索引值(values[center])小于或等于当前索引值(now<--values[i]-->)时,将得到的中间索引(center)向右移动一位重新计算出左索引(left=center+1),继续第2部进行左右索引比较、中间索引值与当前索引值比较。

 

3、直到左索引(left)已经向右移动超过了右索引(right)时就跳出循环,进入下一步。此时如果2.1或2.2步已经执行过,那么此时跳出循环后得到左索引(left),就是当前索引对应数组值将要插入到数组中的索引位置。

 

4、当前索引向左一位(i-1)循环递减得到的索引与第2步骤得到的左索引(left)进行比较。

 

      4.1、如果当前索引左一位(i-1)循环递减的索引结果(i-1-n)大于或等于以上第2步骤得到的左索引时,将前者索引(i-n-1)对应的数组值赋值给该索引的右一位索引(i-1-n+1)对应的数组值。此时在数组中的(i-1-n)索引值和(i-1-n+1)索引值是相同的。接下来进入下一次第4步循环操作。

 

      4.2、如果当前索引左一位(i-1)循环递减的索引结果(i-1-n)小于第三步得到的左索引时,跳出循环进入到下一步。

 

5、判断第3步获得到的左索引与当前索引进行比较。

 

     5.1、如果不相同时,将第1步获取的now覆值给第3步获得到的左索引对应数组中的值。

 

     5.2、如果相同时,进行下一次第2步循环。

 

 

 

 

你可能感兴趣的:(java,排序,二分插入法)