当前位置:首页 > 算法 > 正文内容

【排序】----插入排序

亿万年的星光5年前 (2021-01-28)算法24133
1.基本思想

在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

2.过程

·(1)从第一个元素开始,该元素可以认为已经被排序;

·(2)取出下一个元素,在已经排序的元素序列中从后向前扫描;

·(3)如果该元素(已排序)大于新元素,将该元素移到下一位置;

·(4)重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

·(5)将新元素插入到该位置后;

·(6)重复步骤2~5。



动图演示:


值得收藏的十大经典排序算法


3.参考代码
#include<iostream>
using namespace std;
int main() {
   int arr[]= {12,45,13,88,79,11,52,66}; //定义数组
   int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
   int cur,i,j;
   for(i =1; i<len;i++)
   {
       cur = arr[i]; //待排序元素
       for(j=i-1;j>=0 && arr[j]>cur;j--)
       {
           arr[j+1]=arr[j];
       }
       arr[j+1]=cur; //将待排序元素插入数组中
       
       /*
       for(int i=0;i<len;i++)
           cout<<arr[i]<<" ";
       cout<<endl;
               */
   }
   
   
   return 0;
}

第二种写法

#include<iostream>
using namespace std;
int main()
{
    int arr[]={12,45,13,88,79,11,52,66}; //定义数组
    int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
     int i,j,k;
    for (i =0; i < len; i++)
    {
       /*1目的是为arr[i]找到合适的位置*/
       for (j=i-1; j >= 0; j--) // 在前面有序区间中为a[i]找合适的插入位置
           if (arr[j] <= arr[i]) //找到比a[i]小的位置就退出,插入其后
               break;
       /*2 判断是否找到合适位置*/
       if (j != i - 1)
       {
           int temp = arr[i];
          //将比temp大的数据往后移动
           for (k = i-1; k > j ; k--)
               arr[k+1] = arr[k];
          //将arr[i]放到合适的位置
            arr[k+1] = temp;
       }
       
       /*
       for(int i=0;i<len;i++)
           cout<<arr[i]<<" ";
       cout<<endl;
       */
   }
    return 0;
}  

其他写法:

#include<iostream>
using namespace std;
int main() {
   int arr[]= {12,45,13,88,79,11,52,66}; //定义数组
   int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
   for(int i=1; i<len; i++) { //从第2个元素开始遍历
       int temp=arr[i];//将当前位置的元素取出
       int j;
       for(j=i; j>0; j--) {
           if(temp<arr[j-1]) {//如果这个元素比temp大就覆盖,否则就证明该元素之前已经有序就break
               arr[j]=arr[j-1];//直接用前一个元素进行覆盖
           } else {
               break;
           }
       }
      //将temp中的元素插入合适位置
       arr[j]=temp;
       
       /*
       for(int i=0;i<len;i++)
           cout<<arr[i]<<" ";
       cout<<endl;
       */
   }
}

#include<iostream>
using namespace std;
int main()
{
    int arr[]={12,45,13,88,79,11,52,66}; //定义数组
    int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
    for(int i=1;i<len;i++){ //遍历无序部分,
       int tmp=arr[i],j=i-1; //j为当前下标,tmp为无序部分第一个元素
       while(j>=0&&tmp<arr[j]){ //找到k元素在有序部分的位置
           arr[j+1]=arr[j]; //循环的时候直接右移有序数组,为tmp空出位置
           j--; //不是tmp正确位置,继续循环往前
       }
       arr[j+1]=tmp; //出来的时候j多减1,要加回去
       
       /*  
       for(int i=0;i<len;i++)
           cout<<arr[i]<<" ";
       cout<<endl;
       */
   }
}
4.问题及改进

插入排序是将一个一个的元素单独进行插入,效率较慢,可以考虑把一个有序的序列直接插入到数组中,这样速度就比较快了。也就是希尔排序的思想。


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【算法】动态规划—区间DP问题

一、定义区间DP是动态规划的一种特殊形式,主要用于解决涉及区间操作的问题,比如合并区间、分割区间、区间匹配等。其核心思想是通过枚举区间的划分点,将大区间的问题分解为小区间的子问题,逐步求解并保存中间结...

【贪心】区间调度

【贪心】区间调度

【题目描述】有n项工作,每项工作分别在si时间开始,在ti时间结束。对于每项工作,你都可以选择参与与否。如果选择了参与,那么自始至终都必须全程参与。此外,参与工作的时间段不能重叠(即使是开始与结束的瞬...

【算法】归并排序

【算法】归并排序

一、基本思想归并排序的核心思想是将两个已经有序的子序列合并成一个有序序列。整个过程分为两个主要步骤: 1.分解:将待排序的序列不断二分,直到每个子序列只包含一个元素(此时自然有序) ...

【算法】最大子段和

【算法】最大子段和

【题目描述】给出一个长度位n的序列a,选出其中连续且非空的一段使得这段和最大【输入描述】第一行是一个整数,表示序列的长度n。第二行有n个整数,第i个整数表示序列的第i个数字ai【输出描述】输出一行一个...

【算法】博弈论——取石子游戏

【题目描述】有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取...

【算法】二叉树(1):二叉树及其编号

【算法】二叉树(1):二叉树及其编号

0.前言        二叉树(Binary Tree)的递归定义如下:二叉树要么为空,要么由根结点(root)、左子树(left...