插入排序(Inseretion Sort)

    插入排序的基本思想是,经过i-1遍处理后,a1,a2,..,ai-1己排好序。第i遍处理仅将ai插入a1,a2,..,ai-1的适当位置,使得a1,a2,..,ai又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较aiai-1,如果ai-1 ≤ ai,则a1,a2,..,ai已排好序,第i遍处理就结束了;否则交换aiai-1的位置,继续比较ai-1ai-2,直到找到某一个位置j(1≤j≤i-1),使得aj ≤ aj+1时为止。图1演示了对4个元素进行插入排序的过程。

1 4个元素进行插入排序

在下面的插入排序算法中,为了写程序方便我们可以引入一个哨兵元素a0,它小于a1,a2,..,an中任一记录。所以,我们设元素的类型TElement中有一个常量-∞,它比可能出现的任何记录都小。如果常量-∞不好事先确定,就必须在决定ai是否向前移动之前检查当前位置是否为1,若当前位置已经为1时就应结束第i遍的处理。另一个办法是在第i遍处理开始时,就将ai放入a0中,这样也可以保证在适当的时候结束第i遍处理。

例:

初始序列:

8

3

2

5

9

1

6

i=2

3

8

2

5

9

1

6

i=3

2

3

8

5

9

1

6

i=4

2

3

5

8

9

1

6

i=5

1

2

3

5

8

9

6

i=6

1

2

3

5

8

9

6

i=7

1

2

3

5

6

8

9



程序如下:

直接插入排序:
void docr(float *in,int count)
{
  int i,j,x;
  float temp;
  for(i=1;i<count;i++)
  {
    for(x=0;x<i;x++)
    {
      if((*(in+i))<=(*(in+x)))
      break;
    }
    temp=*(in+i);
    for(j=i;j>x;j--)
    {
      *(in+j)=*(in+j-1);
    }
    *(in+x)=temp;
  }
}
最小比较次数:  最大比较次数:n*n/2
最小移动次数:2n  最大移动次数:n*n/2

二分法插入排序:(比较部分用二分法)常用算法
void docr(float *in,int count)
{
int i,j,x;
int l,r,m;
float temp;
for(i=1;i<count;i++)
    {
    l=0;
    r=i-1;
    temp=*(in+i);
    while(l<=r)
    {
    
        m=(int)((l+r)/2);
        if(temp<=(*(in+m)))
        {
            r=m-1;
        }
        else
        {
            l=m+1;
        }
    }
    for(j=i;j>l;j--)
    {
        *(in+j)=*(in+j-1);
    }
    *(in+l)=temp;
    }
}
移动次数: n*log2(n)
最小移动次数:2n  最大移动次数:n*n/2