排序|归并排序

Deadly 提交于 2020-11-28 04:11:59

      归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。归并:将两个已经排好序的集合合并到一个集合众,并且保证新的集合也是有序的核心点:只有一个元素的集合是已经排好序的集合。归并排序是建立在归并操作上的一种有效的排序算法。归并排序算法是采用分治法(Divide And Conquer)的一个非常典型的应用。
      归并排序流程:
   1.对任意的元素数目为m集合,可以分成m个只有一个元素的子集合。
   2.对其m个元素只有一个的集合实现归并操作,可以得到[m/2]个新的子集合([如果m不是偶数],细节问题,多出的单独保留,即存有[m/2 + 1]个集合),关键的是这些新的集合也是有序的。
   3.重复2的操作,直至最后只有一个集合。
由于各子集合始终保持有序,最终的集合也是有序的,也就得到了排序后的集合,算法目的实现。
      在这里,我们不是用递归来实现。按照思想,归并排序的实现代码如下:

//归并排序
        public static void MergeSort(int[] array)
        {
            //以空间换取时间
            int[] temp = new int[array.Length];
            //size子数组的长度
			//默认为1个元素的子集合(即铁定已排好序的集合)
            int size = 1;
            while (size < array.Length)
            {
			    //有序的子集合两两归并
                MergePass(array, temp, size);
                size += size;//子集合数目在减小,但元素数目在增加
                MergePass(temp, array, size);//使排序后的集合为原数组而非临时数组
                size += size;
            }
        }
//对子数组进行的排序操作
        public static void MergePass(int[] array, int[] temp, int size)
        {
            int index = 0;
            while (index < = array.Length - 2 * size)
            {
                Merge(array, temp, index, index + size - 1, index + 2 * size - 1);
                //位置递进
                index += 2 * size;
            }
			//余下元素,细节处理
            if ((index + size) < array.Length)
            {
                Merge(array, temp, index, index + size - 1, array.Length - 1);
            }
            else
            {
                while (index < array.Length)
                {
                    temp[index] = array[index];
                    ++index;
                }
            }
        }
//归并操作
        public static void Merge(int[] array, int[] temp, 
									int left, int middle, int right)
        {
            int index = left;
            int i = left;
            int j = middle + 1;
            while (true)
            {
                if (array[i] < array[j])
                {
                    temp[index++] = array[i++];
                }
                else
                {
                    temp[index++] = array[j++];
                }

                if (i > middle)
                {
                    while (j < = right)
                    {
                        temp[index++] = array[j++];
                    }
                    break;
                }
                if (j > right)
                {
                    while (i < = middle)
                    {
                        temp[index++] = array[i++];
                    }
                    break;
                }
            }
	}
       归并排序的特点在于没有如同 冒泡选择快速排序的那种元素间的交换,故归并排序是一种稳定的排序算法,简言之就是相等的元素的顺序不会发生改变(当然,具体算法设计细节上可能会出现变换的情况), 这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要。这也是她比下面介绍的快速排序所具有的优势。不过,由于开辟了新的同等大小临时数组,会占用很多资源是其缺陷。
      归并排序的实现种类有很多,并不仅仅局限于本文的算法设计,要想对归并排序有更加深入的了解,读者还要花费很大的心思去查阅资料。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为 2-路归并。本文算法设计即为 2-路归并
       本文系个人总结所得,转载时必须保留本文站点地址: http://blog.iliyang.cn/ | http://www.shopliyang.com.cn/|如果您有疑问,请到 http://www.iliyang.cn/ 论坛讨论!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!