小小c#算法题 - 5 - 插入排序

插入排序是最简单(最容易理解)的一种排序算法。

其基本操作是将一个数插入到已经有序的数组中,那么我们要做的是确定插入到什么位置,所有在这个位置之后的数后移一个位置,从而给这个要插入的数腾出位置。所以关键点是找插入位置。

最简单的办法,从最后一个元素开始找,边找边后移,一直到找到合适的插入位置。

首先,数组第一个元素我们视为有序。第二个元素,跟第一个比较排序之后,前两个元素组成一个有序序列。第n个元素,从前面的有序序列(n-1个元素)的最后一个元素开始比较,直到找到合适的插入位置,插入即可,最终形成一个有序序列。

 代码(c#):

        static void InsertSort(int[] numbers)
        {
            int temp, j;
            for (int i = 1; i < numbers.Length; i++)
            {
                temp = numbers[i];
                j = i;
                while (j > 0 && numbers[j - 1] > temp)
                {
                    numbers[j] = numbers[j - 1];
                    j--;
                }

                numbers[j] = temp;
            }
        }

  

还有一种稍高效一点的方法,因为我们要插入的数组已经是有序的了,所以可以用二分查找找到插入位置,然后后移这个位置之后的元素,插入新值。

代码(c#):

        static void BinaryInsertSort(int[] myArray)
        {
            for (int i = 1; i < myArray.Length; i++)
            {
                if (myArray[i] < myArray[i - 1])
                {
                    int low = 0;
                    int high = i - 1;
                    int mid = (low + high) / 2;

                    // 找到插入位置 low
                    while (low <= high)
                    {
                        if (myArray[i] >= myArray[mid])
                        {
                            low = mid + 1;
                            mid = (low + high) / 2;
                        }

                        if (myArray[i] < myArray[mid])
                        {
                            high = mid - 1;
                            mid = (low + high) / 2;
                        }
                    }

                    // 将插入位置后面的元素后移一个位置,后移之前保存要插入的值myArray[i]
                    int temp = myArray[i];
                    for (int j = i; j > low; j--)
                    {
                        myArray[j] = myArray[j - 1];
                    }

                    myArray[low] = temp;
                }
            }
        }

 

最后,从代码可以看出。直接插入排序的时间复杂度是O(n*n)。虽然折半插入排序减少了关键字间的比较次数,但移动记录的次数不变,所有时间复杂度仍是O(n*n)。

posted @ 2012-04-05 22:52  King Cobra  阅读(235)  评论(0编辑  收藏  举报