常用排序算法_03_插入排序

目录

1、基本思想

2、算法分析

3、代码实现

(1)python实现

(2)scala实现

(3)java实现


1、基本思想

插入排序是将待排序序列看成是两个序列一个是有序序列另外一个是无序序列,依次将无序序列中的每一个元素与有序序列中的元素从后向前进行比较找到合适的位置插入到有序序列中,直到无序序列中的元素全部插入到有序序列中为止。

插入排序在实现上,从后向前扫描有序序列时,需要反复把已排序元素后移,为新插入的元素提供位置。

2、算法分析

第一步,将序列中的第一个元素R[0]看成是有序序列,剩下的元素R[1]-R[n-1]看成是无序序列,R[0]和R[1]比较,如果R[0]>R[1]则将R[0]后移,将R[1]插入到R[0]的位置;

第二步,无序序列中的下一个元素R[2],依次和有序列表的每一个元素从后向前进行比较找到插入位置;

重复上述步骤直到元素有序。

3、代码实现

(1)python实现

#!/usr/bin/python3
# -*- coding: utf-8 -*-


def insert_sort(data: list[int]) -> None:
    for i in range(1, len(data)):
        pre_index = i - 1
        insert_value = data[i]
        while(pre_index >= 0 and insert_value < data[pre_index]):
            data[pre_index + 1] = data[pre_index]
            pre_index -= 1
        data[pre_index + 1] = insert_value
        print(f"第 {i + 1} 轮排序结果:{data}")


def main():
    # data = [3,1,5,2,1,0]
    data = [7, 31, 23, 13, 35, 3]
    print(f"排序前:{data}")
    insert_sort(data)
    print(f"最终结果:{data}")


if __name__ == '__main__':
    main()

(2)scala实现

/**
  *插入排序
  */
object InsertSort {
  def main(args: Array[String]): Unit = {
    val arr = Array(4,1,5,4,11,6,2)
    println(s"排序前结果:${arr.mkString(", ")}")
    insertSort(arr)
//    val arr2 = Array(4,1,5,4,11,6,2)
//    insertSort2(arr2)
  }

  def insertSort(arr:Array[Int]): Unit ={
    for (i <-  1 until arr.length ){
      var preIndex = i - 1
      val insertValue = arr(i)
      // 插入值小于有序列表最后一个值,则有序列表元素后移,再与有序列表前一个值比较
      while (preIndex>=0 && insertValue<arr(preIndex)){
        arr(preIndex + 1) = arr(preIndex)
        preIndex -= 1
      }
      arr(preIndex + 1) = insertValue
      println(s"第 ${i} 次排序结果: ${arr.mkString(", ")}")
    }
    println(s"排序后结果: ${arr.mkString(", ")}")
  }

  // 方式二
  def insertSort2(arr:Array[Int]): Unit ={
    for(i <- 1 until arr.length){ // 无需列表的元素参与比较
      var insertIndex = i
      val insertValue = arr(i)
      for(j <- 0 until i reverse){
        // 无序列表中的每个元素与有序列表的元素依次比较
        // 插入值小于有序列表中的元素则有序列表中的元素后移
        if(arr(j)>insertValue){
          arr(j+1) = arr(j) // 元素后移
          insertIndex = j // 记住待插入空位
        }
      }
      arr(insertIndex) = insertValue
      println(s"第 ${i} 次排序结果: ${arr.mkString(", ")}")
    }
  }
}

排序前结果:4, 1, 5, 4, 11, 6, 2
第 1 次排序结果: 1, 4, 5, 4, 11, 6, 2
第 2 次排序结果: 1, 4, 5, 4, 11, 6, 2
第 3 次排序结果: 1, 4, 4, 5, 11, 6, 2
第 4 次排序结果: 1, 4, 4, 5, 11, 6, 2
第 5 次排序结果: 1, 4, 4, 5, 6, 11, 2
第 6 次排序结果: 1, 2, 4, 4, 5, 6, 11
排序后结果: 1, 2, 4, 4, 5, 6, 11

(3)java实现

public class InsertSort {
    public static void main(String[] args) {
//        int[] arr = {7,31,23,13,35,3};
        int[] arr = {4,1,5,4,11,6,2};
        insertSort(arr);
        int[] arr2 = {7,31,23,13,35,3};
        insertSort2(arr2);
    }

    // 插入排序
    public static void insertSort(int[] arr){
        int insertValue;
        int preIndex;
        for (int i = 1;i < arr.length;i++){
            insertValue = arr[i];
            preIndex = i-1;
            // 插入值小于有序列表最后一个值,则有序列表元素后移,再与有序列表前一个值比较
            while(preIndex>=0 && arr[preIndex]>insertValue){
                arr[preIndex + 1] = arr[preIndex];
                preIndex -= 1;
            }
            // 插入元素大于等于有序列表元素,该元素角标的下一个位置就是插入值的位置
            arr[preIndex + 1] = insertValue;
        }
        System.out.println(arr2Str(arr));
    }

    // 方式二
    public static void insertSort2(int[] arr){
        int insertValue; // 记录插入值
        int i, j;
        for (i = 1;i < arr.length;i++) {
            insertValue = arr[i];
            for (j = i - 1;j >= 0 && arr[j] > insertValue;j--) {
                // 插入值小于有序列表中的值,有序列表元素后移
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = insertValue;
        }
        System.out.println(arr2Str(arr));
    }

    public static String arr2Str(int[] arr){
        StringBuffer sb = new StringBuffer();
        for(int ele : arr){
            if(sb.length()>0){
                sb.append(", ");
            }
            sb.append(ele);
        }
        return sb.toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值