欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

排序算法---直接插入排序

程序员文章站 2024-03-21 13:23:28
...

直接插入算法

基本思想: 是将一个记录插入到已经排好序的有序表中,从而构成一个新的、记录数增1的有序表。(本文由小到大进行排序)

评价算法的三个指标: 时间复杂度、空间复杂度、稳定性

稳定性判断: 在待排序列中存在两个或两个以上的关键字,它们在使用排序算法前后的顺序保持不变,则算法稳定,否则,算法不稳定。
例如:在排序前a[2]=7,a[3]=7,排序后:a[2]的7还是在a[3]的7前面,虽然排序后两个7的位置可能发生变化,但是顺序不发生变化。

算法实现
实现1(不是最优):使用双层循环结构,第一层循环主要用来遍历待排序数据,第一个二层循环从前向后查找要插入的位置,第二个二层循环用来移动已排好序的数据序列,再将待插入数据按顺序插入正确的位置

void InsertSort(int *arr,int len)
{
 int i;//待排序列下标
 int j;//已排序列下标
 int tmp;
 for(i=0;i<len;i++)//遍历待排序列
 {
  tmp=arr[i];//存储当前插入数据
  for(j=0;j<i;j++)//遍历已排序列
  {
   if(tmp<arr[j])//如果tmp大于当前已排序列数据,则跳出
   {
    break;
   }
  }
  for(int k=i;k>=j;k--)//将排好序的序列后移并插入数据
  {
   arr[k]=arr[k-1];
  }
  arr[j]=tmp;
 }
}

分析:此算法有两层for循环,而且不论何种情况,都会执行。所以时间复杂度为O(n^2),空间复杂度为O(1),算法具有稳定性

实现2(优化后的算法):使用双层循环结构,但是由后向前遍历,第一层循环依旧是对待排序列进行遍历,第二层循环由后向前遍历,比较tmp和已排序列数据,如果小于,则在遍历的同时直接移动数据。

void InsertSort(int *arr,int len)
{
 int i;//待排序列下标
 int j;//已排序列下标
 int tmp;
 for(i=0;i<len;i++)//遍历待排序列
 {
  tmp=arr[i];//存储当前插入数据
  for(j=i;j>0;j--)//从后往前遍历已排序列
  {
   if(tmp<arr[j-1])//比tmp大,则向后移
   {
    arr[j]=arr[j-1];
   }
   else//比tmp小或者相等,直接跳出
   {
    break;
   }
  }
  arr[j]=tmp;//将tmp插入当前位置
 }
}

分析:此算法虽然有两层for循环,但是在序列有序的情况下,算法的时间复杂度为O(n),空间复杂度为O(1),算法具有稳定性。

相关标签: 基于c的数据结构