• 数据结构--插入排序


    插入排序

    直接插入排序

    1、算法思想
    每次将一个数插入到已经有序的序列中。

    2、算法步骤(递增)
    ①将第一个元素视为初始有序序列,它已经有序,从第二个元素开始遍历
    ②将需要插入元素赋值给r[0]作为哨兵,比较需要插入元素和它前一个元素的大小,如果大于则不需要改变位置
    若小于前一个元素,则将它插入到有序序列的位置

    #include<iostream>
    using namespace std;
    
    int n=8;
    int a[9]={1000,49,38,65,97,76,13,27,49};
    void InsertSort(int a[])
    {
    	for(int i=2;i<=n;i++)
    	{
    		if(a[i]<a[i-1])
    		{
    			a[0]=a[i];   //插入记录放入监视哨
    			a[i]=a[i-1];  //a[i-1]后移
    			int j;
    			for(j=i-2;a[0]<a[j];j--)
    			{
    				a[j+1]=a[j];  //记录逐个后移,直到找到插入位置
    			}
    			a[j+1]=a[0]; //插入到正确位置
    		}
    	}
    }
    
    int main()
    {
    	cout<<"排序前:"<<endl;
    	for(int i=1;i<=n;i++)
    	{
    		printf("%d ",a[i]);
    	}	
    	cout<<endl<<"排序后:"<<endl;
    	InsertSort(a);
    	for(int i=1;i<=n;i++)
    	{
    		printf("%d ",a[i]);
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    3、算法分析
    时间复杂度:O(n^2)
    空间复杂度:O(1)
    算法特点:
    ①稳定排序
    ②算法简便,易实现
    ③也适用于链式存储结构
    ④更适合于初始记录基本有序的情况,当初始记录无序,n较大时,不适合采用

    折半插入排序

    1、算法思想:直接插入排序采用顺序查找法当前记录在已排好序的序列中的插入位置,将此查找利用折半查找实现,即称为折半插入排序

    2、算法步骤:
    ①插入元素赋值给哨兵r[0]
    ②进行折半查找
    ③将插入点及后面所有元素后移

    这里需要特别注意折半插入的写法和平时不一样,因为这里是比较大小而不是找相等的值
    因此不需要考虑相等情况,一直递归下去low和high最终会相等

    void InsertSort(int a[])
    {
    	for(int i=2;i<=n;i++)
    	{
    		a[0]=a[i];
    		int low=1,high=i-1;
    		int mid;
    		while(low<=high)
    		{
    		    mid=(low+high)/2; //折半
    			if(a[0]>a[mid]) low=mid+1; //插入点在前一子表 
    			else high=mid-1; //插入点在后一子表
    		
    		}
    		for(int j=i-1;j>=high+1;j--)
    		a[j+1]=a[j]; //记录后移
    		a[mid]=a[0];
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3、算法分析
    ①时间复杂度:O(n^2)
    ②空间复杂度:O(1)
    算法特点
    ①稳定排序
    ②由于使用了折半查找,不能使用链式结构
    ③适合初始记录无序,n较大的情况

    希尔排序

    1、算法思想:直接插入排序时,当排序的记录个数较少且待排序序列的关键字基本有序时,效率较高。希尔排序基于以上两点,从“减少记录个数”和“序列基本有序”两个方面对直接插入排序进行了改造

    2、算法步骤:
    ①第一趟取增量d1把全部记录分为d个组,每间隔d1的记录分在同一组,在各个组中进行直接插入排序
    ②依次取增量d2、d3依次类推

    注意:增量序列必须是互质的且递减,最后一个必须是1

    #include<iostream>
    using namespace std;
    
    int n=8;
    int a[9]={1000,49,38,65,97,76,13,27,49};
    int dt[3]={5,3,1};
    void ShellInsert(int a[],int dk)
    {
    	for(int i=dk+1;i<=n;i++)
    	{
    		if(a[i]<a[i-dk])
    		{
    			a[0]=a[i];
    			int j;
    			for(j=i-dk;j>0&&a[0]<a[j];j-=dk)
    				a[j+dk]=a[j];
    			a[j+dk]=a[0];
    		}
    	}
    }
    
    void ShellSort(int a[],int dt[],int t)
    {
    	for(int i=0;i<t;i++)
    	{
    		ShellInsert(a,dt[i]);
    	}
    }
    
    int main()
    {
    	cout<<"排序前:"<<endl;
    	for(int i=1;i<=n;i++)
    	{
    		printf("%d ",a[i]);
    	}	
    	cout<<endl<<"排序后:"<<endl;
    	ShellSort(a,dt,3);
    	for(int i=1;i<=n;i++)
    	{
    		printf("%d ",a[i]);
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3、算法分析
    ①时间复杂度:O(n^3/2)
    ②空间复杂度:O(1)

    4、算法特点
    ①跳跃式导致它是不稳定算法
    ②不能用于链式结构
    ③适合初始记录无序,且n较大

  • 相关阅读:
    智能机器人无法智能对话_关于智能语音机器人使用中可能出现的问题
    Kotlin学习(一)
    项目部署之安装和配置Canal
    华为HCIP Datacom H12-831 卷23
    MyBatisPlue-03
    面试题——git
    Linux中shell的使用(零基础学习笔记)
    基于Echarts实现可视化数据大屏突发事件预警平台大数据投屏系统模板
    揭示GPT Tokenizer的工作原理
    蓝牙低能耗安全连接 – 数值比较
  • 原文地址:https://blog.csdn.net/weixin_47020721/article/details/126074817