1. 程式人生 > >小橙書閱讀指南(三)——插入排序

小橙書閱讀指南(三)——插入排序

stat 指定 improve @override n) alt img 解釋 style

算法描述:通常人們在整理撲克的方法是一張一張的來,將每一張牌插入到其他已經有序的牌中的適當位置。在算法的實現中,為了給要插入的元素騰出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

小橙書閱讀指南(三)——插入排序