监视哨的作用在“排序”专栏中已经转发过,不再赘述。
现在通过代码,进一步体会监视哨的作用。
/*
名称:直接插入排序
编写时间:20180430 下午14:50
编写动机:因为我之前一直对这种排序很陌生
重点内容:理解监视哨的作用
*/
#include <stdio.h>
/*直接插入排序将整个元素分为两部分,一部分是排好的,另一部分是待排的,每次选待排的第一个往排好的里面插*/
void Insert_Sort(int a[],int n)//直接插入排序,含监视哨
{
int i,j;
for(i=2;i<=n;i++)//元素从1开始,一个元素没有必要排序,因此i从2开始一直到最后一个
{
a[0]=a[i];//a[0]是监视哨,这里存的是待排元素的第一个元素
for(j=i-1;a[j]>a[0];j--)//这一步很巧妙,也是精华所在,a[j]>a[0]表示如果排好的有大于监视哨的就应该右移一格,这里少了一步j>=0的if语句,因此n次循环就能少n次判断,自然就提速了
a[j+1]=a[j];//右移,实质是要对a[j+1]进行改变
a[j+1]=a[0];//最后a[j]肯定满足a[j]<=a[0],那么直接让 a[j+1]=a[0]就好了,实质是要对a[j+1]进行改变
}
}
void Insert_Sort_Bad(int a[],int n)//直接插入排序,不含监视哨
{
int i,j,k;
for(i=2;i<=n;i++)
{
k=a[i];
for(j=i-1;j>=1;j--)
if(a[j]>k)// 没有加监视哨的话这里就要多写一个if语句,因此n次循环就比加监视哨的多n次比较,费时啊!
a[j+1]=a[j];
else
break;
a[j+1]=k;
}
}
int main()
{
int n,i,j,a[100],b[100];
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
Insert_Sort(a,n);
Insert_Sort_Bad(b,n);
for(i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
for(i=1;i<=n;i++)
printf("%d ",b[i]);
}
![](https://i-blog.csdnimg.cn/blog_migrate/23f421bdf9e5a61b2b085f1124da39ec.png)