数据结构与算法-插入排序

264 阅读1分钟

插入排序执行流程:

  1. 将序列分为2个部分,头部是已经排序好的,尾部是待排序的
  2. 从头扫描每一个元素,将它插入到头部的合适位置,使头部数据依然有序

1:堆排序

实现一(比较交换)

2:基于交换的实现 代码实现:

/**
 * 插入排序
 *
 * @author zhangj
 * @date 2020/9/23
 */
public class InsertSort {

	private int[] elements;

	public InsertSort(int[] elements) {
		this.elements = elements;
	}

	public void sort() {
		for (int begin = 1; begin < elements.length; begin++) {
			int curr = begin;
			while (curr > 0 && elements[curr - 1] > elements[curr]) {
				//交换
				int tmp = elements[curr - 1];
				elements[curr - 1] = elements[curr];
				elements[curr] = tmp;
				
				curr--;
			}
		}
	}
}

平均时间复杂度O(n2),空间复杂度O(1)

实现二(比较挪动)

实现一的实现中,如果后面的数小于前面的数,我们就交换,要交换就要执行固定的三行代码,其实我们可以不交换,实现思路如下:

  1. 先将待插入的元素备份
  2. 前面数据大于待插入元素时,前面元素往后挪一位
  3. 将待插入元素放到最终的位置

3:比较挪动

代码实现:

 public static void sort(int[] array) {
        for (int i = 1; i < array.length; i++) {
            //记录待插入的值
            int current = array[i];
            int curr = i;
            while (curr > 0 && array[curr - 1] > current) {
                //往后挪一位
                array[curr] = array[curr - 1];
                curr--;
            }
            //插入合适的位置
            array[curr] = current;
        }
    }

实现三(二分搜索)

每次拿到待插入元素去有序数列中使用二分查找,找到合适的插入位置,再把待插入元素插入。

代码实现:

public class InsertSort {

    private int[] array;

    public InsertSort(int[] array) {
        this.array = array;
    }

    /**
     * 排序
     */
    public void sort() {
        for (int i = 1; i < array.length; i++) {
            insert(i, search(i));
        }
    }

    /**
     * 二分搜索查找index位置处元素要插入的位置
     */
    private int search(int index) {
        int begin = 0;
        int end = index;
        while (begin < end) {
            int mid = (begin + end) >> 1;
            if (array[index] < array[mid]) {
                end = mid;
            } else {
                begin = mid + 1;
            }
        }
        return begin;
    }

    /**
     * 把source处的元素插入到dest位置
     */
    public void insert(int source, int dest) {
        int value = array[source];
        for (int i = source; i > dest; i--) {
            array[i] = array[i - 1];
        }
        array[dest] = value;
    }
}

总结: 上述三种实现方法的平均时间复杂度都是O(n2),只是不同的实现比较次数不同而已。 记得点赞哦!