算法概述:插入排序是稳定排序,具体流程如下:
1、从第一元素开始,认为第一个元素已经被排序;
2、取出下一个元素,在已经排序的元素序列中从后向前进行比较
3、如果取出的元素小于被比较的元素,则向前移;
4、如果取出的元素大于或等于比较的元素,则直接插入当前位置;
5、重复取出下一个元素进行2-4步骤;
流程图如下:

算法分析时间复杂度:O(n²)
最坏情况时间复杂度:O(n²);
(是该序列已经反向排序,即:{5, 4, 3, 2, 1}。需要比较的次数是 1 + 2 + 3 + 4 即:n(n + 1) / 2。关注最大增长量级,所以时间复杂度是:O(n²);
最好情况是:O(n);(正向排序,每个元素只需比较一次,总共n-1次比较,0次交换);
平均情况是:O(n²);
空间复杂度是O(1);
c#代码实现:
public class InsertionSort
    {
        public int[] a = { 12, 15, 9, 20, 6, 31, 24 };
        public void Sort()
        {
            for (int i = 1; i < a.Length; i++) // 从第2个元素开始,跟自己前面的进行比较
            {
                for (int j = i; j > 0; j--) // 从后往前,每一个元素进行比较
                {
                    if (a[j - 1] > a[j]) // 如果前面的元素大,则交换位置,并拿交换后的位置继续往前比较
                    {
                        int t = a[j];
                        a[j] = a[j - 1];
                        a[j - 1] = t;
                    }
                    else // 如果前面的比我小,则不再向前比较,跳出该元素
                    {
                        break;
                    }

                }
            }
            foreach (int i in a)
            {
                Console.WriteLine("{0} ", i);
            }
        }
    }
erlang 代码实现:目前没有找到好的实现方式,采用了性能很差的列表实现,有大量reverse与++操作
insertion_sort() ->
    [H | T] = [12, 15, 9, 20, 6, 31, 24],
    insertion_sort(T, [H]). %% 默认第一个元素已经排好序
 
insertion_sort([], List) ->
    lists:reverse(List);
insertion_sort([H1 | T1], [H2 | T2]) when H1 >= H2 -> %% 比前一个元素大,直接跳出该元素比较循环
    insertion_sort(T1, [H1, H2 | T2]);
insertion_sort([H1 | T1], [H2 | T2]) -> %% 比前一个元素小,与再前面的元素进行比较
    L = insertion_replace(H1, [H2 | T2], []),
    insertion_sort(T1, L).
 
insertion_replace(H1, [], Acc) ->
    lists:reverse([H1 | Acc]);
insertion_replace(H1, [H2 | T2], Acc) when H1 >= H2 -> %% 比前面的元素大,跳出该元素循环
    lists:reverse(Acc) ++ [H1, H2 | T2];
insertion_replace(H1, [H2 | T2], Acc) -> %% 比前面的元素小,继续往前进行比较
    insertion_replace(H1, T2, [H2 | Acc]).