排序之插入排序(简单插入排序,希尔排序)

插入排序:

阐述:

在已排序集合中插入待排序集合中的某一元素,使得已排序集合仍然有序,直到待排序集合大小为1。

时间复杂度:

插入已排序集合的时间复杂度是O(N),遍历待排序集合的时间复杂度是O(N),所以插入排序的时间复杂度是O(N*N)。

稳定性

插入排序主要就是在挪动待排序集合的位置,并且将元素插入到合适位置,不会打乱相同元素的相对位置,所以是稳定的。

效果图:

代码(c#):

       /// <summary>
        /// 插入排序
        /// </summary>
        public static void DoInsertionSort()
        {
            List<int> listNum = new List<int>() { 3, 10, 11, 2, 6, 4, 2, 17, 19 };

            //两层循环,外循环是遍历未排序集合,内循环用来遍历已排序集合
            for (int indexUnOrder  = 1; indexUnOrder < listNum.Count; indexUnOrder++)
            {
                int itemInsert = listNum[indexUnOrder];
                int indexOrdered = indexUnOrder - 1; //遍历已排序集合
                while (indexOrdered > -1 && itemInsert < listNum[indexOrdered]) //itemInsert==listNum[j]的情况没有写进去,使得插排算法是稳定的
                {
                    listNum[indexOrdered + 1] = listNum[indexOrdered]; //向后挪动元素
                    indexOrdered--;
                }
                //j 指向要插入的位置
                listNum[indexOrdered + 1] = itemInsert;
                //LogWrite.LogPlain(DisplayList(listNum, new List<int> { j+1},'<','>'));
            }
        }

 

希尔排序

阐述:

使用增量d对集合进行分组(也就是索引相隔d个元素的数放在一组),然后在组内进行插入排序,有节奏地缩小增量d,然后再进行组内插入排序,如此往复,直到增量d为1(也就是把集合分为一个组)。

算法描述:

1.按照增量d分组

2.遍历所有分组,并进行组内插入排序

3.减小增量d,如果d不小于1,回到第1步,

时间复杂度:

增量的递减复杂度是O(lgN),分组的遍历(按照增量d的位置开始遍历)和组内数组的移动(按照增量d的跨度挪动),这个复杂度据说暂时没有说法,只是说,比插入排序O(N*N)好。

稳定性:

分组进行的组内移动能保证稳定,但是组与组之间没有约束,很容易改变相同元素的相对位置,所以希尔排序是不稳定的。

算法关键字:

增量,分组,插入排序

效果图:

代码(c#):

        /// <summary>
        /// 希尔排序
        /// </summary>
        public static void DoShellSort()
        {
            List<int> listNum = new List<int>() { 25, 19, 6, 58, 34, 10, 7, 98, 160, 0 };
            int indexIncreasement = listNum.Count / 2;   //设置希尔排序的增量索引
            int indexGroup;  //遍历分组的索引
            int indexGroupItem; //指向分组项的索引
            int temp;
            //LogWrite.LogPlain("排序的数据如下:");
            //LogWrite.LogPlain(DisplayList(listNum));
            //遍历增量
            while (indexIncreasement >= 1)
            {
                LogWrite.LogPlain(string.Format("增量是:{0}", indexIncreasement));
                //遍历分组
                for (indexGroup = indexIncreasement; indexGroup < listNum.Count; indexGroup++) //indexI 用来遍历分组
                {
                    temp = listNum[indexGroup];
                    indexGroupItem = indexGroup - indexIncreasement;
                    //在分组内插入数据
                    while (indexGroupItem >= 0 && listNum[indexGroupItem] > temp)
                    {
                        //LogWrite.LogPlain(DisplayList(listNum, new List<int> { indexGroupItem + indexIncreasement, indexGroupItem }, '<', '>'));
                        listNum[indexGroupItem + indexIncreasement] = listNum[indexGroupItem];
                        indexGroupItem -= indexIncreasement;
                    }
                    listNum[indexGroupItem + indexIncreasement] = temp;

                    //if (indexGroupItem < 0)
                    //    indexGroupItem = indexGroupItem + indexIncreasement;
                    //LogWrite.LogPlain(DisplayList(listNum, new List<int>() { indexGroup, indexGroupItem }));
                }
                indexIncreasement = indexIncreasement / 2;    //缩小增量
            }
        }

 

 

 

posted on 2013-02-21 13:51  豆沙包没有肉  阅读(278)  评论(0编辑  收藏  举报

导航