前言
随着大数据时代的到来,一般的排序算法已经满足不了我们的需求,这时候需要引入几种排序,今天我们来说一下直接插入排序。
直接插入排序
直接插入排序是一种简单的排序方法,它的基本思想是依次将每个记录插入到一个已排好的有序表中去,从而得到一个新的,记录数增加1的有序表。
效果图
代码
类C语言描述
void StraightInsertSort(List R,int n)//对顺序表进行直接插入排序
{
int i,j;
for(i=2;i<=n;i++)//n为表长,从第二个记录起进行插入
{
R[0]=R[i];//第i个记录复制为岗哨
j=i-1;
While(R[0].key<R[j].key)//与岗哨比较,直至键值不大于岗哨键值
{
R[j+1]=R[j];//将第j个记录复制给第j+1个记录
j--;
}
R[j+1]=R[0];//将第i个记录插入到序列中
}
}
C#描述
static void Main(string[] args)//客户端主程序
{
int[] R = {0 ,6, 5 ,3 ,1 ,8, 7, 2, 4 };//定义数组(同上图)
int count = InsertSort(R);
Console.WriteLine("排序后数组:");
for (int i = 1; i <= R.Length-1; i++)
{
Console.Write(R[i] + ",");//打印数组
}
Console.WriteLine();
Console.WriteLine("排序次数:"+count);//打印排序次数
Console.ReadKey();
}
private static int InsertSort(int[] R)//C#直接插入排序
{
int count = 0;//初始化排序次数
int n = R.Length-1;
int j = 0;
for (int i = 2; i <= n; i++)//开始排序
{
R[0] = R[i];//将第i个值放入岗哨R[0]中
j = i - 1;
while (R[0]<R[j])//比较岗哨和岗哨之前的序列(有序区),如发现比岗哨大的,则将该位右移一位
{
R[j + 1] = R[j];//向右移一位
j--;
}
R[j+1] = R[0];//将岗哨中的值放入最终位置
if(j+1 != i)//判断是否发生了移位,如有,则排序次数加一
{
count ++;
}
}
return count;
}
注:这里特意和类C语言对比了一下,发现了一点小问题:在C#中,我们习惯数字索引从0开始,刚开始我也是那么敲的,将所有涉及到n的地方改为n-1,岗哨R[0]用一个temp变量代替即可,这时出现j下标越界,原因很简单,j--到j小于0了,while循环中还在判断是否“temp<R[j]”,于是在while语句中加入了判断:while (j>=0 && temp<R[j])(此中j>=0一定要在temp<R[j]之前),代码可以执行,并没有什么问题;突然想到书中提到一句,R[0]可监视j,能避免每次在while循环中判断,再看看我的代码,这不正是每次都要判断j是否越界吗,于是开始好奇的研究这个R[0]和temp究竟有什么不同,很快,就发现了原因,当j=0时,R[0]<R[j]恒不成立,必定跳出while循环,所以才有了这版代码。
直接插入排序的算法简单,易于理解,容易实现,待排记录数量很大时,一般不选用直接插入排序。
总结
各种排序对比图
另附:插入排序舞蹈视频