插入排序

本文详细介绍了插入排序的基本原理,包括直接插入排序和二分插入排序的实现过程及代码示例,并对比了它们的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://www.tianshouzhi.com/api/tutorials/basicalgorithm/324

 插入排序(Insert Sort)将待排序的数组分为2部分:有序区,无序区。其核心思想是每次取出无序区中的第一个元素,插入到有序区中。 有序与无序区划分,就是通过一个变量标记当前数组中,前多少个元素已经是局部有序了。

  在排序开始的时候,把数组的第1个元素当成有序区(即有序区只有一个元素),其余的所有元素当做无序区。

   之后在往有序区插入无序去第一个元素值时,有序区中比这个值小(或者大)的元素都要右移一个位置。右移并不会覆盖的数组中已有的数据项值,因为我们总是取无序区中的第一个元素插入,右移也只是覆盖了我们取出的这个元素的位置而已。当无序区为空时,排序完成。

  插入排序根据具体实现方式又分为:直接插入排序二分插入排序(又称折半插入排序),链表插入排序希尔排序(又称缩小增量排序)。属于稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置) 。

直接插入排序

代码实现:

      
  1. public class InsertSort {
  2.     public static void sort(int[] arr,boolean asc){
  3.             //有序区最后一个元素位置
  4.         int orderedLastIndex=0;//开始排序时,将有序区结束位置设为0 (开始位置总是0),对应的无序区范围就是 1-arr.length
  5.         for (int i = orderedLastIndex+1; i < arr.length; i++) { //迭代无序区中的每一个元素,依次插入有序区中
  6.             int temp=arr[i];//记录无序区中的第一个元素值
  7.             int insertIndex=i;//在有序区中插入的索引的位置,刚开始就设置为自己的位置
  8.             for (int j = orderedLastIndex; j >= 0; j--) { //从有序区从后往前开始比较
  9.                 if(asc){//升序,有序区中比当前无序区中元素大的都右移一个位置
  10.                     if(arr[j]>temp){
  11.                         arr[j+1]=arr[j];
  12.                         insertIndex--;//有序区每移动一次,将插入位置-1
  13.                     }else{
  14.                         break;//有序区当前位置元素<=无序区第一个元素,那么之前的元素都会<=,不需要继续比较
  15.                     }
  16.                 }else{//升序,有序区中比当前无序区中元素小的都右移一个位置
  17.                     if(arr[j]<temp){
  18.                         arr[j+1]=arr[j];
  19.                         insertIndex--;
  20.                     }else{
  21.                         break;
  22.                     }
  23.                 }
  24.             }
  25.             arr[insertIndex]=temp;
  26.             orderedLastIndex++;
  27.         }
  28.     }
  29.  
  30.     public static void main(String[] args) {
  31.         int[] arr=new int[]{1,5,6,8,9,4,3,3};
  32.         System.out.println("排序数组:"+ Arrays.toString(arr));
  33.         sort(arr,true);
  34.         System.out.println("升序排列:"+Arrays.toString(arr));
  35.         sort(arr,false);
  36.         System.out.println("降序排列:"+Arrays.toString(arr));
  37.     }
  38. }

运行程序:

排序数组:[1, 5, 6, 8, 9, 4, 3, 3]

升序排列:[1, 3, 3, 4, 5, 6, 8, 9]

降序排列:[9, 8, 6, 5, 4, 3, 3, 1]

直接插入排序的效率:

  • 在第1趟排序中,最多需要比较1次

  • 在第2趟排序中,最多需要比较2次

  • .....

  • 在第n-1趟排序中,最多需要比较n-1次

  • 因此最多需要比较n*(n-1)/2次

   冒泡排序也是需要比较n*(n-1)/2次,但是二者不同之处在于,冒泡排序肯定是需要比较n*(n-1)/2次,插入排序只有在最坏的情况下才会需要n*(n-1)/2次,回顾上例中的出现的break,当我们发现某个元素不符合时,就直接跳出,有序区之前的元素都不会再比较了,从概率的角度来说,实际上只需要和有序区中一半的元素进行比较,因此需要除以2,即插入排序比较的平均时间复杂度是n*(n-1)/4,所以有的时候我们会看到 插入排序比冒泡排序效率高一倍 的说法

二分插入排序

  二分插入排序与直接插入排序的区别是,直接插入排序是迭代有序区中的每一个数据项与无序区中的第一个元素进行比较,二分插入排序实际上是充分利用了有序区的特定,我们知道,对于一个有序的数组,我们可以利用二分查找快速定位某个数字应该插入的位置,在定位了这个位置之后,只需要将这个位置以及之后的元素右移一位,将腾出来的位置直接插入无序区中的第一个元素即可,减少了比较次数。



内容概要:本文探讨了在MATLAB/SimuLink环境中进行三相STATCOM(静态同步补偿器)无功补偿的技术方法及其仿真过程。首先介绍了STATCOM作为无功功率补偿装置的工作原理,即通过调节交流电压的幅值和相位来实现对无功功率的有效管理。接着详细描述了在MATLAB/SimuLink平台下构建三相STATCOM仿真模型的具体步骤,包括创建新模型、添加电源和负载、搭建主电路、加入控制模块以及完成整个电路的连接。然后阐述了如何通过对STATCOM输出电压和电流的精确调控达到无功补偿的目的,并展示了具体的仿真结果分析方法,如读取仿真数据、提取关键参数、绘制无功功率变化曲线等。最后指出,这种技术可以显著提升电力系统的稳定性与电能质量,展望了STATCOM在未来的发展潜力。 适合人群:电气工程专业学生、从事电力系统相关工作的技术人员、希望深入了解无功补偿技术的研究人员。 使用场景及目标:适用于想要掌握MATLAB/SimuLink软件操作技能的人群,特别是那些专注于电力电子领域的从业者;旨在帮助他们学会建立复杂的电力系统仿真模型,以便更好地理解STATCOM的工作机制,进而优化实际项目中的无功补偿方案。 其他说明:文中提供的实例代码可以帮助读者直观地了解如何从零开始构建一个完整的三相STATCOM仿真环境,并通过图形化的方式展示无功补偿的效果,便于进一步的学习与研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值