• 直接插入排序


    直接插入排序,插入排序(insert sort)的基本方法是:每步将一个待排序的元素,按其排序码大小,插入到前面已经排好序的一组元素的适当位置上去,直到元素全部插入为止。

    算法描述:
    直接插入排序(insert sort)的基本思想是:当插入第 i (i≥1)个元素时,前面的v[0],v[1]…VIi-1]已经排好序:这时,用V[i]的排序码与V[i-1],V[i一2],…的排序码顺序进行比较,找到插入位置即将V[i]插人,原来位置上的元素向后顺移。假设其中v[0],…v[i-1]已经是一组有序的元素,V[i],V[i+1],…,V[n-1]是待插入的元素,排序过程从i=1起,每一趟执行完后,i增加1,把第i个元素插入到前面有序的元素序列中去,使插入后元素序列V[0],V[1],…V[i]仍保持有序。

    算法过程:

    原始序列:3、44、38、5、47、15、36、 26、27、2、46、4、19、50、48

    放上插入排序的动态图让大家更容易理解这个过程:

    在这里插入图片描述结果:{2、3、4、5、19、26、27、36、38、44、46、47、48、50}

    插入排序的C++,Java,Python实现

    本篇文章会给大家介绍直接插入排序的三种语言的实现,在后面的文章中我会更新其他的插入排序,在这里先给大家分享简单一点的插入排序,循序渐进

    插入排序C++实现代码:

    #include <iostream>
    using namespace std;
    #include <vector>
    #include <time.h>
    vector<int> get_random(int n, int N);
    const int MAX_NUM=10000;
    int data[100];//定义一个产生数组储存100个随机数
    void InsertSort(int n);//直接插入排序
    void output(int n);
    int main() 
    {
    	srand((unsigned int)time(0));
    	vector<int> randsample=get_random(100,MAX_NUM);//产生100个0-MAZX_NUM的随机数,每次产生的随机数不一样
    	int size=randsample.size();
    	//输出最开始时未排序时的顺序:
    	cout<<"随机数的顺序:"<<endl;
    	for(int i=0;i<randsample.size();i++)
    	{
    		cout<<randsample[i]<<" ";
    	}
    	cout<<endl;
    	clock_t start,finish;//定义一个测量一段程序运行时间的前后值
    	double totaltime;//总的运行时间
    	
    	//测试插入排序
    	cout<<"执行插入排序后:"<<endl;
    	for(int i=0;i<randsample.size();i++)
    	{
    		data[i]=randsample[i];
    	}
    	start=clock();
    	InsertSort(size);
    	finish=clock();
    	output(size);
    	totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
    	cout<<"运行时间:"<<totaltime<<endl;
    }
    //产生随机数的函数
    vector<int> get_random(int n, int N)
    {
    	vector<int> vec(N);//N代表初始状态分配的空间大小
    	vector<int> out_vec;
    	for(int i=0;i<N;++i)
    	{
    		vec[i]=i;
    	}
    	for (int i=0;i<n;++i)
    	{
    		int rand_value=rand()%N;
    		out_vec.push_back(vec[rand_value]);
    		vec[rand_value]=vec[N-1];//将数组vec的元素
    		N--;
    	}
    	return out_vec;
    }
    void InsertSort(int n)
    {
    	int tmp;
    	int i,j;
    	int count=0;
    	int count1=0;
    	for(i=1;i<n;i++){
    		if(data[i]<data[i-1]){
    			count++;
    			tmp=data[i];
    			j=i-1;
    			while(j>=0&&tmp<data[j]){
    				count++;
    				data[j+1]=data[j];
    				count1++;
    				j--;
    			}
    			data[j+1]=tmp;
    		}
    	}
    	cout<<"比较次数: "<<count<<"  移动次数:  "<<count1<<endl;
    }
    void output(int n)
    {
    	for(int i=0;i<n;i++)
    	{
    		cout<<data[i]<<" ";
    	}
    	cout<<endl;
    }
    
    

    测试结果展示:
    在这里插入图片描述

    插入排序Java代码实现

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    public class insertSort
    {
      public static void main(String[] args)
      {
        Object []arr = getRandomNumList(100,0,10000).toArray();
        int[] ins = new int [100] ;
        System.out.println("排序前:");
        for(int i = 0; i < arr.length; i++) {
          String s=arr[i].toString();
          ins[i]= Integer.parseInt( s );
          System.out.println(ins[i]);
          }
        System.out.println("排序后:");
        int[] ins2 = insertsort(ins);
        for(int i = 0; i < arr.length; i++) {
          System.out.println(ins2[i]);
          }
      }
      
      public static int[] insertsort(int[] data){
    	  int tmp;
    	  int n = data.length-1;
    		int i,j;
    		for(i=1;i<=n;i++){
    			if(data[i]<data[i-1]){
    				tmp=data[i];
    				j=i-1;
    				while(j>=0&&tmp<data[j]){
    					data[j+1]=data[j];
    					j--;
    				}
    				data[j+1]=tmp;
    			}
    		}
        return data;
      }
       //定义生成随机数并且装入集合容器的方法
        //方法的形参列表分别为:生成随机数的个数、生成随机数的值的范围最小值为start(包含start)、值得范围最大值为end(不包含end)  可取值范围可表示为[start,end)
        public static List getRandomNumList(int nums,int start,int end){
            //1.创建集合容器对象
            List list = new ArrayList();
    
            //2.创建Random对象
            Random r = new Random();
            //循环将得到的随机数进行判断,如果随机数不存在于集合中,则将随机数放入集合中,如果存在,则将随机数丢弃不做操作,进行下一次循环,直到集合长度等于nums
            while(list.size() != nums){
                int num = r.nextInt(end-start) + start;
                if(!list.contains(num)){
                    list.add(num);
                }
            }
            return list;
        }
    }
    
    

    插入排序Python代码实现

    import random
    def InsertSort(nums):
        for i in range(len(nums) - 1):
            if(nums[i]<nums[i-1]):
                tmp = nums[i]
                j = i - 1
                while(j>=0 and tmp<nums[j]):
                    nums[j+1] = nums[j]
                    j=j-1
                nums[j+1]=tmp
    
        return nums
    
    def main():
    
        arr =[]
        while(len(arr)<100):
            x=random.randint(0,10000)
            if x not in arr:
                arr.append(x)
        InsertSort(arr)
        print(arr)
    
    if __name__ == "__main__":
        main()
    

    算法分析:

    若设待排序的元素个数为n,则该算法的主程序执行n-1趟。因为排序码比较次数和元素移动次数与元素排序码的初始排列有关,所以在最好情况下,即在排序前元素已经按排序码大小从小到大排好序了,每趟只需与前面的有序元素序列的最后一个元素的排序码比较1次,总的排序码比较次数为n-1,元素移动次数为0。而在最差情况下,即第 i 趟时第 i 个元素必须与前面个元素都做排序码比较,并且每做1次较就要做1次数据移动,则总的排序码比较次数KCN和元素移动次数RMN分别为:

    KCN=i=1n1isum_{i=1}^{n-1}{i}=n(n-1)/2approx n2n^2/2.
    RMN=i=1n1(i+2)sum_{i=1}^{n-1}{(i+2)}=(n+4)(n-1)/2approx n2n^2/2

    从以上讨论可知,直接插入排序的运行时间和待排序元素的原始排列顺序密切相关。若待排序元素序列中出现各种可能排列的概率相同,则可取上述最好情况和最差情况的平均情况。在平均情况下的排序码比较次数和元素移动次数约为n2n^2/4。因此,直接插入挂序
    的时间复杂度为O(n2n^2)。直接插入排序是一种稳定的排序方法。

    继续加油!

    以上就是本次给大家分享的直接插入排序,后面还会写其他的插入排序,如果有什么不足之处欢迎大家指出,留言,互相学习,共同进步。希望得到大家的支持,你的支持就是我前进的动力,接下来我会持续更新其他的排序算法,敬请期待!(写博客学到了很多东西,嘻嘻,欢迎大家来我的个人博客玩耍啊)

  • 相关阅读:
    Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡
    SP10570 LONGCS
    Luogu P3975 [TJOI2015]弦论
    hihocoder #1457 : 后缀自动机四&#183;重复旋律7
    Luogu SP8222 NSUBSTR
    SP7258 SUBLEX
    Luogu P4070 [SDOI2016]生成魔咒
    [清华集训2016]组合数问题
    [NOIP2018TG]保卫王国
    [note]克鲁斯卡尔重构树
  • 原文地址:https://www.cnblogs.com/xiangjunhong/p/12482468.html
Copyright © 2020-2023  润新知