排序算法

Java实现归并排序

最后都变了- 提交于 2020-03-06 12:32:12
百度百科:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并 。 归并操作 : 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。 如 设有数列{6,202,100,301,38,8,1} 初始状态:6,202,100,301,38,8,1 第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3; 第二次归并后:{6,100,202,301},{1,8,38},比较次数:4; 第三次归并后:{1,6,8,38,100,202,301},比较次数:4; 总的比较次数为:3+4+4=11; 逆序数为14 算法描述 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经 排序 序列之和,该空间用来存放合并后的序列 第二步:设定两个 指针 ,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 图例: java代码实现: package

归并排序

主宰稳场 提交于 2020-03-06 12:31:13
归并操作 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。 如 设有数列{6,202,100,301,38,8,1} 初始状态:6,202,100,301,38,8,1 第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3; 第二次归并后:{6,100,202,301},{1,8,38},比较次数:4; 第三次归并后:{1,6,8,38,100,202,301},比较次数:4; 总的比较次数为:3+4+4=11,; 逆序数为14; 算法描述 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经 排序 序列之和,该空间用来存放合并后的序列 第二步:设定两个 指针 ,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 代码实现 func mergeSort(r []int) []int { length := len(r) if length <= 1 { return r } num := length / 2 left := mergeSort(r[:num]) right := mergeSort(r[num:]) return merge

交换排序

荒凉一梦 提交于 2020-03-06 12:30:14
1 交换排序基本思想 交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。 应用交换排序基本思想的主要排序方法有:冒泡排序(Bubble sort)和快速排序(Quick sort)。 2 冒泡排序 2.1 冒泡排序思想 第一趟排序:首先将第一个记录的关键字和第二个记录的关键字比较,若为逆序,则将两个记录交换之,然后比较第二个和第三个的关键字。以此类推,直至第n-1个记录和第n个记录关键字比较为止。该过程为第一趟排序,使得最大的关键字排到了最后面。第二趟排序:对前n-1个记录进行相同操作,完成后使得次大的关键字排在n-1位置上。以此类推,进行第三、四次排序直到排序结束。判断排序结束条件是:在一趟排序过程中没有发生过交换记录的操作。一般第i趟排序是从第1个元素到(n-i+1)个记录依次比较相邻两个记录关键字,并在逆序时交换记录。 总结便是:共比较多少趟,每趟比较多少次。一个两重循环。 2.2 冒泡排序算法实现 public static void bubbleSort(int a[]) { int lenth = a.length; int temp; //共比较lenth-1趟 for (int i = 0; i < lenth - 1; i++) { //每轮比较length-1-j次 for (int j = 0; j

排序算法——快速排序

拜拜、爱过 提交于 2020-03-06 12:26:41
今天介绍快速排序,这也是在实际中最常用的一种排序算法,速度快,效率高。就像名字一样,快速排序是最优秀的一种排序算法。 思想 快速排序采用的思想是分治思想。 快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。 举例说明一下吧,这个可能不是太好理解。假设要排序的序列为 2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移 2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置 2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面 2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变 经过第一轮的快速排序,元素变为下面的样子 [1] 2 [4 9 3 6 7 5] 之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束

C#各种排序算法代码实现

被刻印的时光 ゝ 提交于 2020-03-06 11:48:49
转自: https://blog.csdn.net/sniper007/article/details/53080131 排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。 将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。 分类 稳定排序:假设在待排序的文件中,存在两个或两个以上的记录具有相同的关键字,在用某种排序法排序后,若这些相同关键字的元素的相对次序仍然不变,则这种排序方法是稳定的。其中冒泡,插入,基数,归并属于稳定排序,选择,快速,希尔,堆属于不稳定排序。 就地排序:若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间为O(1),则称为就地排序。(百度百科) 冒泡排序 已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1

基础算法之快速排序Quick Sort

做~自己de王妃 提交于 2020-03-06 11:47:38
原理 快速排序(Quicksort)是对 冒泡排序 的一种改进。 从数列中挑出一个元素,称为" 基准 "(pivot); 排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在本次排序退出之后,该基准就处于数列的中间位置。这个称为 分区 (partition)操作; 递归 地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 例子 将无序数组[3,6,4,2,5,1]进行快速排序 1) , 先把第一项[3]取出来作为基准 依次与其余项进行比较(3出列后大喝一声,比我小的站前边,比我大的站后边,行动吧!霸气侧漏~), 如果比[3]小就放[3]前边,2 1都比[3]小,全部放到[3]前边 如果比[3]大就放[3]后边,6 4 5比[3]大,全部放到[3]后边, 一趟排完后变成下边这样: 排序前:3,6,4,2,5,1 排序后:2,1,3,6,4,5 2) , 对前面一半[2,1]继续进行快速排序 重复步骤1)后变成下边这样: 排序前:2,1 排序后:1,2 前面一半排序完成,总的数组为: 排序前:2,1,3,6,4,5 排序后:1,2,3,6,4,5 3) ,对后面一半[6,4,5]继续进行快速排序 重复步骤1)后变成下边这样: 排序前:6,4,5 排序后:4,5,6 后面一半排序完成,总的数组为: 排序前

排序算法之快速排序(Quicksort)解析

旧街凉风 提交于 2020-03-06 11:47:29
一.快速排序算法的优点,为什么称之为快排? Quicksort是对归并排序算法的优化,继承了归并排序的优点,同样应用了分治思想。 所谓的分治思想就是对一个问题“分而治之”,用分治思想来解决问题需要两个步骤: 1.如何“分”?(如何缩小问题的规模) 2.如何“治”?(如何解决子问题) 快排的前身是归并,而正是因为归并存在不可忽视的缺点,才产生了快排。归并的最大问题是需要额外的存储空间,并且由于合并过程不确定,致使每个元素在序列中的最终位置上不可预知的。针对这一点,快速排序提出了新的思路:把更多的时间用在“分”上,而把较少的时间用在“治”上。从而解决了额外存储空间的问题,并提升了算法效率。 快排之所以被称为“快”排,是因为它在平均时间上说最快的,主要原因是硬件方面的,每趟快排需要指定一个“支点”(也就是作为分界点的值),一趟中涉及的所有比较都是与这个“支点”来进行比较的,那么我们可以把这个“支点”放在寄存器里,如此这般,效率自然大大提高。除此之外,快排的高效率与分治思想也是分不开的。 二.算法思想 按照快排的思想,对一已知序列排序有如下步骤: 1.指定“支点” 注意,是“指定”,并没有明确的约束条件,也就是说这个支点是任意一个元素,一般我们选择两种支点:当前序列首元,或者随机选取 两种方式各有优劣,前者胜在简单,但可能影响算法效率 快排中,支点的最终位置越靠近中间位置效率越高

归并排序(MergeSort)

夙愿已清 提交于 2020-03-06 11:45:49
//版权所有 Anders06 于2007年10月25日 归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。 1、 基本思想 ( 1 ) 分治法的基本思想 分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 ( 2 ) 归并排序的基本基本步骤 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 分解 : 讲n个元素分成n/2 个元素的子序列 解决 : 用合并并排序对两个子序列递归地排序 (在对子序列排序时,长度为1时递归结束) 合并 : 合并两个已经排好序的子列序以得到排序结果 以扑克牌为例, 假设有两堆牌面朝上地放在桌上,每一堆都是排好序的,最小的牌在最上面。我们希望将两堆牌合并成升序的一堆牌。基本步骤包括在面朝上的两堆牌中,选择顶上两张较小的一张,将其取出放入到输出堆,重复此动作,知道有一堆为空为止,然后吧另一堆所剩下的牌面朝下放入到输出堆即可。 合并排序的时间为 O(n). 2、 算法分析 ( 1 )时间复杂度 Merge过程运行的时间为O(n),

直接插入排序

戏子无情 提交于 2020-03-06 09:11:57
插入排序是把一个记录插入到已排序的有序序列中,使整个序列在插入该记录后仍然有序。插入排序中较简单的一种方法是直接插入排序,其插入位置的确定方法是将待插入的记录与有序区中的各记录自右向左依次比较其关键字值的大小。 核心算法:直接插入排序 设定待插入元素左边的元素都是按从小到大有序排列 ①从s[2]开始往右依次 选择待插入的元素 s[i]存入s[0]中,则s[i]空闲。 ②将待插入的元素s[i] 与它左边的各元素比较 (往左第一个,往左第二个……依次),若有比它大的,则将与它比较的元素向 右移 一个单位。 ③将s[0]中存放的待 插入 的元素插入s[j+1]的位置 可 自定义函数insort() 将一组数据从小到大排列: void insort(int s[],int n) { int i,j; for(i=2;i<=n;i++) { s[0]=s[i]; j=i-1; while(s[0]<s[j]) { s[j+1]=s[j]; j–; } s[j+1]=s[0]; } } 注意: ① 监视哨 的作用,存放后面的数据,防止前面的数据在后移时导致后面的数据丢失。 详见 直接插入排序——监视哨的作用 ②对于 数组中数据的输入和输出 要结合循环结构才能使用 ③ 以数组为参数的函数的使用 : 定义:函数返回值类型 函数名(形参数组类型 形参数组名[])

选择排序法-Selection Sort

柔情痞子 提交于 2020-03-06 09:08:18
一、O(n 2 )的排序算法 (1)基础 (2)编码简单,易于实现,是一些简单情景的首选 (3)在一些特殊情况下,简单的排序算法更有效 (4)简单的排序算法思想衍生出复杂的排序算法 (5)作为子过程,改进更复杂的排序算法 二、选择排序-Selection Sort (1)对下面数组从小到大排序 (2)找到数组中最小的元素1和第一个位置8进行交换,此时1这个元素就已经在最终数组排好序的位置了 (3)此时,找数组中第二小的元素为2,和当前数组第一个没有排序的位置的元素6进行交换,此时元素2也已经归位,以此类推 【代码】 <selection_sort.cpp> # include <iostream> # include <algorithm> # include <string> # include "Student.h" # include "SortTestHelper.h" using namespace std ; //选择排序核心代码 template < typename T > void selectionSort ( T arr [ ] , int n ) { for ( int i = 0 ; i < n ; i ++ ) { //寻找[i,n)区间里的最小值 int minIndex = i ; for ( int j = i + 1 ; j < n ; j ++