冒泡排序两两比较指的是: 未排序的相邻元素之间的两两比较,对于已排好的元素,它不再访问。
而插入排序中的比较则是: 在未排序的元素中,取出一个,将它与已排好的元素进行比较,从而确定其位置。
是某未排元素,与诸多已排元素的逐次比较。
其排序图解如下:
程序代码:
1) 比较一次 , 移动一次
[cpp] view plaincopy
- //比较一次,移动一次
- void StraightInsertionSort(int *p,int n)
- {
- int i,j,t;
- for (i=1;i<n;i++) // 0...i-1 是已排好元素 i...n-1是未排元素
- {
- t=p[i]; // 记录下 将要与排好序的元素 进行比较的那个 未排序元素
- for (j=i-1;j>=0;j--)
- {
- if (t<p[j]) // 比较一次, 移动一次
- {
- p[j+1]=p[j];
- p[j]=t;
- }else{
- break; // 已经将t 存放到目标位置
- }
- }
- }
- }
2) 先找到合适位置,再集体移动
[cpp] view plaincopy
- // 先找位置 再集体移动
- void StraightInsertionSort(int *p,int n)
- {
- int i,j,t;
- for (i=1;i<n;i++) // 0...i-1 是已排好元素 i...n-1是未排元素
- {
- t=p[i]; // 记录下 将要与排好序的元素 进行比较的那个 未排序元素
- // 找t所应在的位置
- for (j=i-1;j>=0;j--)
- {
- if (t>=p[j]) // 说明t应该放在j+1 位置上
- break;
- }
- for (int k=i-1;k>j;k--)
- {
- p[k+1]=p[k];
- }
- p[j+1]=t;
- }
- }
3) 对于情况2,可以用二分查找法优化程序, 如下:
[cpp] view plaincopy
- void BinaryInsertionSort(int *p, int n)
- {
- int i,j,k;
- for (i=1;i<n;i++) // 0...i-1 是已排好元素 i...n-1是未排元素
- {
- int t=p[i]; // 记录下 将要与排好序的元素 进行比较的那个 未排序元素
- int iLeft=0;
- int iRight=i-1;
- int iMiddle=(iLeft+iRight)/2;
- while (iLeft<=iRight)
- {
- if (t>p[iMiddle])
- {
- iLeft=iMiddle+1;
- }
- if (t<p[iMiddle])
- {
- iRight=iMiddle-1;
- }
- if (t==p[iMiddle])
- {
- j=iMiddle; // 0....j 不需移动 j+1...i-1 需要后移一位 t 应保存在第j+1位置
- break;
- }
- iMiddle=(iLeft+iRight)/2;
- }
- if (iLeft>iRight)
- {
- j=iLeft-1; // 0....j 不需移动 j+1...i-1 需要后移一位 t应保存在第j+1位置
- }
- for (k=i-1;k>j;k--)
- {
- p[k+1]=p[k];
- }
- p[j+1]=t;
- }
- }