排序算法稳定性

归并排序

感情迁移 提交于 2020-01-24 01:50:37
1、什么是归并排序?   归并排序是属于分冶法的一种排序方式,归并排序将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将他们合并成一个子序列。合并两个子序列的过程也就是两路归并。 2、时间复杂度和空间复杂度   归并排序是一种稳定的排序算法,一般用于对总体无序,但是各子项相对有序的数列。   归并排序的主要问题在于它需要一个与待排序数组一样大的辅助数组空间,所以空间复杂度为T(n)。   由于归并排序每次划分时两个子序列的长度基本一样,所以归并排序最好、最差和平均时间复杂度都是(nlogn)。 3、算法描述   将原本的待排序的数列不断的分解为两个子序列,直到子序列长度为1时开始合并   利用递归的方式分解数列   创建一个和原数组待排序字段长度一致的新数组,分别遍历字段的前半部分和后半部分取值,取其中较小的值   直到一部分遍历结束,将另一部分剩余的值全部赋予新数组   将新数组复制到原数组的待排序字段 4、java代码实现 public class Test { public static void main(String[] args) { // TODO Auto-generated method stub int[] A = {5,2,4,5,6,2,3,6,7,9}; sort(A,1,9);//第一个5不参加排序 for(int l=0;l<A

005-排序算法-归并排序

不想你离开。 提交于 2020-01-23 23:06:05
一、概述   基本思想:采用分治法,将已有的有序子序列合并,得到一个完整的有序序列 排序方法 时间复杂度(平均) 时间复杂度 (最坏) 时间复杂度(最好) 空间复杂度 稳定性 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 分治算法   分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。   分治算法的一般步骤:   (1)分解,将要解决的问题划分成若干规模较小的同类问题;   (2)求解,当子问题划分得足够小时,用较简单的方法解决;   (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。 1.1、算法说明      下图更加能够说明分治法      1.2、算法实现   将长度为 n 的序列分成两个长度为 2/n 的子序列,然后对着两个子序列进行归并排序,子序列又被分成子序列再进行归并排序,最终对有序子序列进行归并,得到最终的有序序列。   根据具体的实现,归并排序包括" 从上往下 "和" 从下往上 "2种方式。 public static int[] mergeSort(int[] nums, int l, int h) { if (l == h) return new int[] { nums[l] }; int mid = l + (h

Java十大排序算法总结

回眸只為那壹抹淺笑 提交于 2020-01-23 22:16:59
排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序; O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。 关于稳定性 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。 名词解释: n:数据规模 k:"桶"的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 1.1冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成

数据结构-排序: 两路归并排序算法 - 子逸 - 博客园

社会主义新天地 提交于 2020-01-22 20:08:43
数据结构-排序: 两路归并排序算法 - 子逸 - 博客园 数据结构-排序: 两路归并排序算法 归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。 1、算法基本思路  设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 (1)合并过程  合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字,取关键字较小的记录复制到R1[p]中,然后将被复制记录的指针i或j加1,以及指向复制位置的指针p加1。  重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录依次复制到R1中即可。 (2)动态申请R1  实现时,R1是动态申请的,因为申请的空间可能很大,故须加入申请空间是否成功的处理。 2、归并算法 void Merge(SeqList R,int low,int m,int high) {//将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的 //子文件R[low..high] int i=low,j=m+1,p=0; //置初始值

数据结构与算法之排序算法

橙三吉。 提交于 2020-01-21 15:03:38
排序 内部排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 交换排序 冒泡排序 快速排序 归并排序 基数排序 外部排序 内部排序 插入排序 直接插入排序 是对于欲排序的元素以插入的方式找寻元素的适当位置,以达到排序的目的 思路: 插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。 如上图,我们所说的有序表是前面有括号包着的表,后面是无序表。我们每一次都把无序表的第一个元素插入到有序表中,并与有序表的最后一个元素比较,如果比它大就查到后面去,如果比它小,就一个一个往前比较,直到找到位置位置。 代码实现 // 插入排序 public static void insertSort ( int [ ] arr ) { // 使用逐步推导的方式来讲解,便于理解 // 从最后一个开始 遍历到最后一个 for ( int i = 1 ; i < arr . length ; i ++ ) { // 定义待插入的数 int insertVal = arr [ i ] ; int insertIndex = i - 1 ; /

2020.1.20每日一题“归并排序”

佐手、 提交于 2020-01-21 04:42:45
归并排序是什么 归并排序顾名思义有一个化归合并的过程,那要合并在这之前就有分离,这就是归并排序的步骤:先将要排序的一串数字劈开,劈到最小有序数列(也就是一个一个的时候,只有一个那肯定有序啊);第二步再将他们逐渐合并,继而变成一个有序数列。 为什么要用归并排序 算法复杂度: 最好情况:O(nlogn) 最坏情况:O(nlogn) 平均情况:O(nlogn) 空间复杂度:O(n) 稳定性:稳定 从以上的数据 可以看出归并排序比普通的排序在复杂度上有了很好的提升。 归并排序的代码实现: 上面这个代码还可用于求逆序数对的个数。 关键就是这段代码: 来源: CSDN 作者: LeBronGod 链接: https://blog.csdn.net/LebronGod/article/details/104055745

数据结构之排序基础知识笔记

北战南征 提交于 2020-01-18 22:14:17
概述 最近在温习数据结构,现在针对排序算法写一篇随笔,其中附带原理说明和代码。 插入排序 直接插入排序(Straight Insertion Sort)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次 从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。 假设{20,30,40,10,60,50}中的前3个数已经排列过,是有序的了;接下来对10进行排列。示意图如下: 图中将数列分为有序区和无序区。我们需要做的工作只有两个:(1)取出无序区中的第1个数,并找出它在有序区对应的位置。(2)将无序区的数据插入到有序区;若有必要的话,则对有序区中的相关数据进行移位。 时间复杂度和稳定性 直接插入排序的时间复杂度是O(N2)。 假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1!因此,直接插入排序的时间复杂度是O(N*N)。 直接插入排序是稳定的算法,它满足稳定算法的定义。 算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的。 插入排序JAVA实现 1 import static javaTest.SortUtils

排序(冒泡排序、快速排序)

て烟熏妆下的殇ゞ 提交于 2020-01-16 14:56:44
基本排序分类图: 关于排序的稳定性 在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。 一、 冒泡排序 冒泡排序的基本思想:每次比较两个 相邻 的元素,如果它们的顺序错误就把他们交换过来 冒泡排序的原理:每一趟只能确定将一个数归位,如果有n个数进行排序,只需将n-1个数归位,也就是说要进行n-1趟操作,而每一趟都需要从第1位开始进行相邻两个数的比较 1 #include <stdio.h> 2 #define MAX 7 3 4 int main(void) 5 { 6 int i, j, t; 7 int a[MAX] = {1, 5, 3, 7, 6, 4, 2}; 8 9 //冒泡排序核心部分 10 for (i = 0; i < MAX - 1; i++) //n个数排序只需要n-1趟 11 { 12 for (j = 0;j < MAX - i; j++) //每一趟比较到n-i结束 13 { 14 if (a[j] < a[j + 1])//降序排列 15 { 16 t = a[j]; 17 a[j] = a[j + 1]; 18 a[j + 1] = t; 19 20 } 21

排序一 冒泡排序

泪湿孤枕 提交于 2020-01-16 11:10:04
目录 要点   算法思想 算法分析   冒泡排序算法的性能   时间复杂度   算法稳定性 优化 完整参考代码   JAVA版本 参考资料 相关阅读 要点 冒泡排序是一种 交换排序 。 什么是交换排序呢? 交换排序 :两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。 算法思想 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。 假设有一个大小为 N 的无序序列。冒泡排序就是要 每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排 。 图 - 冒泡排序示例图 以上图为例,演示一下冒泡排序的实际流程: 假设有一个无序序列 { 4. 3. 1. 2, 5 } 第一趟排序:通过两两比较,找到第一小的数值 1 ,将其放在序列的第一位。 第二趟排序:通过两两比较,找到第二小的数值 2 ,将其放在序列的第二位。 第三趟排序:通过两两比较,找到第三小的数值 3 ,将其放在序列的第三位。 至此,所有元素已经有序,排序结束。 要将以上流程转化为代码,我们需要像机器一样去思考,不然编译器可看不懂。 假设要对一个大小为 N 的无序序列进行升序排序(即从小到大)。 (1)

排序(上)

放肆的年华 提交于 2020-01-14 22:05:35
算法-排序 算法排序执行效率 排序算法的内存消耗 排序算法的稳定性 冒泡排序 插入排序 归并排序 快速排序 桶排序 计数排序 基数排序 算法排序执行效率 最好情况、最坏情况、平均情况的时间复杂度 时间复杂度的系数、常数、低阶 比较次数和交换次数 排序算法的内存消耗 算法的内存消耗可以通过空间复杂度来衡量,针对排序算法的空间复杂度,我们有个新的概念, 原地排序 。原地排序算法,就是特指空间复杂度为O(1)的排序算法。 排序算法的稳定性 如果待排序的序列中存在值相等的元素,经过排序后,相等元素之间原有的先后顺序不变,我们称这种算法称为稳定的排序算法。 冒泡排序 冒泡排序只会操作相邻的两个数据,每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系的要求。每一次冒泡会让至少一个元素移动到它应该在的位置,重复复n次,就完成了n个数据的排序工作。 public static void bubbleSort ( int [ ] a , int n ) { if ( n <= 1 ) return ; for ( int i = 0 ; i < n - 1 ; i ++ ) { boolean flag = false ; for ( int j = 0 ; j < n - i - 1 ; j ++ ) { if ( a [ j ] > a [ j + 1 ] ) { int temp =