小橙书阅读指南——插入排序

Posted learnhow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小橙书阅读指南——插入排序相关的知识,希望对你有一定的参考价值。

算法描述:通常人们在整理扑克的方法是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。在算法的实现中,为了给要插入的元素腾出1个空间,我们需要将其余所有元素在插入之前都向右移动1位。这种算法叫插入算法。

算法图示:

技术分享图片

 算法解释:在基础版本中通常的做法是,当新元素需要被插入有序数组的时候,从右向左依次交换。直到新元素到达它合适的位置。

Java代码示例:

import common.ArraysGenerator;
import common.Sortable;

import java.io.IOException;
import java.util.Arrays;

public class Insertion implements Sortable<Integer> {

    @Override
    public void sort(Integer[] array) {
        for (int i = 1; i < array.length; ++i) {
            for (int j = i; j > 0; --j) {
                // 如果数组 array[index] < array[index-1] 交换位置
                if (array[j] < array[j - 1]) {
                    int tmp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = tmp;
                }
            }
        }
    }

    public static void main(String arg[]) throws IOException {
        // 从文件中读取数组的静态方法,指定文件名和数组长度
        Integer[] arr = ArraysGenerator.fromFile("disorder.txt", 1000000);

        Insertion insertion = new Insertion();
        long start = System.currentTimeMillis();
        insertion.sort(arr);
        long end = System.currentTimeMillis();

        System.out.println(Arrays.toString(arr));
        System.out.println(end - start);
    }
}

Qt/C++代码示例:

void Insertion::sort(int * arr, int len)
{
    for (int i = 1; i < len; ++i) {
        for (int j = i; j > 0; --j) {
            if (arr[j] < arr[j - 1]) {
                int tmp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = tmp;
            }
        }
    }
}

 

算法改进:仍然考虑人们整理扑克的情形,当需要插入的时候并仅仅做了一次操作并且当新牌不需要整理的时候直接摸下一张手牌。因此,要大幅提高插入排序的速度并不难, 只需要在内循环中将较大的元素都向右移动和不是交换两个元素的位置。

算法图示:

技术分享图片

Java代码示例:

import common.Sortable;

public class InsertionImprove implements Sortable<Integer> {
    @Override
    public void sort(Integer[] array) {
        for (int i = 1; i < array.length; ++i) {
            // 如果array[index] 大于 有序数组array[0-index)的最后1位
            if (array[i] > array[i - 1]) {
                continue;
            }
            for (int j = i; j > 0; --j) {
                // 如果存在 array[j-1] <= array[index] < array[j]
                if (array[i] < array[j] && array[i] >= array[j - 1]) {
                    int tmp = array[i];
                    // 数组array[j-i)的部分 都向后移动1位
                    for (int n = i; n > j; --n) {
                        array[n] = array[n - 1];
                    }
                    array[j] = tmp;
                    break;
                }
            }
        }
    }
}

Qt/C++代码示例(略)

总的来说,插入排序对于部分有序数组十分搞笑,也很适合小规模数组。这很重要,因为这些类型的数组在实际应用经常出现,并且他们也是高级排序算法的中间过程。

相关链接:

Algorithms for Java

Algorithms for Qt

以上是关于小橙书阅读指南——插入排序的主要内容,如果未能解决你的问题,请参考以下文章

小橙书阅读指南——选择排序

小橙书阅读指南——快速排序和三向切分快速排序

小橙书阅读指南——归并排序的两种实现

小橙书阅读指南——二叉查找树

小橙书阅读指南——优先队列和索引优先队列

小橙书阅读指南——散列表