插入排序(Java)

本文详细介绍了三种常见的插入排序算法:直接插入排序、折半插入排序和希尔排序,并提供了完整的Java实现代码。通过这些代码示例,读者可以更好地理解每种排序算法的工作原理及其应用。

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

常见的插入排序有直接插入排序、折半插入排序和希尔排序三种。接下来我就将这三种的实现附代码如下:

package com.xqq.插入排序;

public class Sort<T> {

    @SuppressWarnings("unchecked")
    public void insertSort(T[] arrays) {
        if (arrays == null || arrays.length <= 1)
            return;
        int i, j;
        for (i = 1; i < arrays.length; i++) {
            // 有序区的数据后移而占用了该记录,所以用temp保存
            // 用于比较,T需要实现Comparable接口
            Comparable<? super T> temp = (Comparable<? super T>) arrays[i]; 
            for (j = i - 1; j >= 0; j--) {
                int cmp = temp.compareTo(arrays[j]);
                if (cmp >= 0) {  //找到插入位置退出循环
                    break;
                }
                // 有序区的元素大于待插入的元素
                System.out.println("arrays[" + (j) + "]=" + arrays[j] + 
                        "->arrays[" + (j + 1) + "]= " + arrays[j+1]);
                arrays[j + 1] = arrays[j];   // 将该有序区的元素后移一位
            }
            arrays[j + 1] = (T) temp;
        }
    }

    // 在查找插入位置时,对有序区使用折半查找,提高查找效率
    // 从时间上比较,折半插入排序仅仅减少了关键字的比较次数,却没有减少记录的移动次数,故时间复杂度仍为O(n^2)
    @SuppressWarnings("unchecked")
    public void binaryInsertSort(T[] arrays){
        if(arrays == null || arrays.length <= 1) return;

        int i, j, low, high, mid;
        for(i = 1; i < arrays.length; i++){
            Comparable<? super T> temp = (Comparable<? super T>) arrays[i];
            low = 0;
            high = i - 1;
            // 利用折半查找找到插入点
            while(low <= high){
                mid = (low + high) / 2;
                int cmp = temp.compareTo(arrays[mid]);
                if(cmp < 0)
                    high = mid - 1;
                else 
                    low = mid + 1;
            }
            // 移动
            for(j = i - 1; j >= high + 1; j--)
                arrays[j + 1] = arrays[j];
            // 插入
            arrays[high + 1] = (T) temp;
        }
    }

    // 希尔排序, d 为增量
    @SuppressWarnings("unchecked")
    private void shellPass(T [] arrays, int d){
        if(arrays == null || arrays.length <= 1) return;

        int i, j;
        for(i = d; i < arrays.length; i++){
            Comparable<? super T> temp = (Comparable<? super T>) arrays[i];

            for(j = i - d; j >= 0; j -= d){

                int cmp = temp.compareTo(arrays[j]);

                if(cmp >= 0)
                    break;

                arrays[j + d] = arrays[j];
            }
            arrays[j + d] = (T) temp;
        }
    }

    // 希尔排序
    public void shellSort(T [] arrays, int [] d){
        for(int i = 0; i < d.length; i++)
            shellPass(arrays, d[i]);
    }
}

测试代码:
package com.xqq.插入排序;

import java.util.Arrays;


public class Main {

    public static void main(String[] args) {
        Integer [] arrays = {4, 5, 7, 3, 3, 2, 1};
        int [] d = {5, 3, 1};
        Sort<Integer> sort = new Sort<Integer>();
        System.out.println(Arrays.asList(arrays).toString());
//      sort.insertSort(arrays);
//      sort.binaryInsertSort(arrays);
        sort.shellSort(arrays, d);
        System.out.println(Arrays.asList(arrays).toString());
    }
}
### Java 实现插入排序算法 插入排序是一种简单直观的排序算法,适用于小规模数据集和部分有序的数据。以下是基于提供的参考资料以及标准实现方式的具体说明。 #### 插入排序的核心思想 插入排序通过构建有序序列逐步完成整个列表的排序过程。对于未排序的部分,每次取出一个元素,在已排序的序列中找到合适位置并插入其中[^1]。 #### 算法具体实现 下面是一个完整的 Java 版本的插入排序代码: ```java import java.util.Arrays; public class InsertionSort { public static void main(String[] args) { int[] arr = {2, 5, 9, 4, 1, 6}; // 输出原始数组 System.out.println("排序前:" + Arrays.toString(arr)); // 调用插入排序函数 insertionSort(arr); // 输出排序后的数组 System.out.println("排序后:" + Arrays.toString(arr)); } public static void insertionSort(int[] array) { for (int i = 1; i < array.length; i++) { int key = array[i]; int j = i - 1; // 移动较大的元素向右 while (j >= 0 && array[j] > key) { array[j + 1] = array[j]; j--; } // 将当前元素插入到正确位置 array[j + 1] = key; } } } ``` 上述代码实现了基本的插入排序逻辑。程序首先定义了一个待排序的整型数组 `arr`,并通过调用 `insertionSort()` 方法对其进行排序[^2]。 #### 关键步骤解析 1. **外层循环**:从第二个元素开始遍历数组(索引为 1),因为第一个元素默认视为已排序。 2. **内层循环**:将当前元素与前面已经排序好的子数组逐一比较,如果发现有更大的数,则将其向右移动一位。 3. **插入操作**:当找到合适的插入位置时,将当前元素放置于此处[^3]。 #### 时间复杂度分析 - 平均时间复杂度为 \(O(n^2)\),最坏情况下也是 \(O(n^2)\),发生在输入数组完全逆序的情况下。 - 最佳情况下的时间复杂度为 \(O(n)\),此时输入数组已经是升序排列。 #### 插入排序的优点与局限性 优点在于其实现简单、空间效率高,并且在处理几乎有序的小规模数据时表现出色。然而,由于其平方级的时间复杂度,它并不适合大规模数据集的排序需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值