排序算法稳定性

数据结构与算法 python--第五节 排序(二)选择排序

↘锁芯ラ 提交于 2020-03-06 02:08:24
文章目录 5 排序 5.1 冒泡排序 5.2 选择排序 选择排序分析 自己初步实现的代码 实现代码(正确) 5 排序 5.1 冒泡排序 数据结构与算法 python–第五节 排序(一)冒泡排序 5.2 选择排序 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下: 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。 选择排序分析 排序过程:(此处以选择最大元素为例,代码实现为选择最小元素) 自己初步实现的代码 def select_sort ( alist ) : n = len ( alist ) for j in range ( n - 1 ) : for i in range ( j + 1 , n ) : if alist [ j ] > alist [ i ] : alist [ j ] , alist [ i ] = alist [ i ] ,

C++实现排序算法之希尔排序

一世执手 提交于 2020-03-05 15:36:24
C++实现排序算法之希尔排序: 时间复杂度:O(n^1.5); 算法稳定性:不稳定的排序算法; 希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt < dt-1 <… < d2 < d1),即所有记录放在同一组中进行直接插入排序为止。 该方法实质上是一种分组插入方法 比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时

C++实现排序算法之快速排序

白昼怎懂夜的黑 提交于 2020-03-05 15:07:24
C++实现排序算法之快速排序 时间复杂度:O(N*logN); 算法稳定性:不稳定的排序算法; 1、快速排序的简单介绍   算法思想:基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法),然后分别从数组的两端扫描数组,设两个指示标志(low指向起始位置,high指向末尾),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换low和high位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换low和high位置的值,如此往复循环,直到low>=high,然后把基准点的值放到high这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。 2、快速排序算法的特点 • 快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较; • 最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n n); • 在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数

排序算法总结二

偶尔善良 提交于 2020-03-02 18:06:31
本文接排序算法总结一 3. 冒泡排序 冒泡排序的基本思想:以正序排列为例,我们首先要将最大的数沉到最底下,从第一个数开始,比较相邻的两个数,如果为逆序则交换这两个数,重复这个操作直到倒数第二个数,此时最大的数已沉到最底下;然后再从第一个数开始,用同样的方法将次大的数沉到次底下,重复这个过程直到排序成功。代码如下: void PaoSort1(vector<int>& a) { int length = a.size(); for (int i = 0; i < length - 1; i++) { for (int j = 0; j < length -1-i; j++) { if (a[j]>a[j+1]) Swap(a[j], a[j+1]); } } } 注意上面的内循环j的判断条件,每当外部循环i加1表示,底部多了一个数,所以j跳出条件为length-1-i,这个过程其实是泡沫沉底。而真正的冒泡是从底部向上升,这个过程与沉底类似,只不过内部循环中的j从最后一个数开始,每次循环后j值递减,而循环跳出条件为j<i. 上述代码的缺点是当序列已经有序了,而循环没有结束,会继续进行比较操作,这样便增加了运行时间。为了提高速度我们可以设置一个标记来查看是否进行了交换,并把这个标签加入到外部循环的判断条件,这样如果没有交换说明已经排序完成,程序返回。代码如下: void Paosort2

Java 实现常见内排序

北城以北 提交于 2020-03-01 19:58:58
一、内排序 1、排序基本概念 (1)什么是排序?   排序指将一个数据元素集合或者序列 按照某种规则 重新排列成一个 有序的集合或者序列。分为内排序、外排序。排序算法的好坏直接影响程序的执行速度以及存储空间的占有量。 (2)什么是内排序?外排序?   内排序:指待排序的序列完全存放在内存中所进行的排序过程(不适合大量数据排序)。   外排序:指大数据的排序,待排序的数据无法一次性读取到内存中,内存与外存需进行多次数据交换,以达到排序的目的。 (3)什么是稳定排序?   稳定排序指的是 相等的数据经过某种排序算法排序后,仍能保证它们的相对顺序与未排序之前相同。   比如一个序列 a1 a2 a3 a4 a5, 且 a1 < a2 = a3 < a4 < a5。   若经过某种排序算法后,结果仍为 a1 < a2 = a3 < a4 < a5,那么该排序算法是稳定的。   若经过某种排序算法后,结果为 a1 < a3 = a2 < a4 < a5,那么该排序算法是不稳定的。 2、内排序分类 (1)按种类划分:   插入排序:直接插入排序、希尔排序。   选择排序:选择排序、堆排序。   交换排序:冒泡排序、快速排序。   归并排序:归并排序。 (2)按稳定排序划分:   稳定排序:冒泡排序、归并排序、直接插入排序。   非稳定排序:快速排序、希尔排序、堆排序、选择排序。 (3)比较:

数据结构—排序

谁说我不能喝 提交于 2020-03-01 02:54:30
排序:假设含有 n 个记录的序列为 ,其相应的关键字分别为 ,需确定 的一种排列 ,使其相应的关键字满足 ( 非递减或非递增 )关系,即使得序列成为 一个按关键字有序的序列 ,这样的操作就称为 排序 。 相信大家都有着极其丰富的网上购物的经验,现在网上购物已经非常成熟,对用户来说带来了很大的方便。 假如我想买一台 iPhone4 的手机,于是上了某电子商务网站去搜索。可搜索后发现(如下图所示),有 8863 个相关的物品,如此之多,这叫我如何选择。我其实是想买便宜一点的,但是又怕遇到骗子,想找信誉好的商家,如何做? 下面的有些购物达人给我出主意了,排序呀。对呀,排序就行了(如下图所示)。我完全可以根据自己的需要对搜索到的商品进行排序,比如按信用从高到低、再按价格从低到高,将最符合我预期的商品列在前面,最终找到我愿意购买的商家,非常的方便。 网站是如何做到快速地将商品按某种规则有序的呢?—— 排序 。 1. 排序的基本概念与分类 排序是我们生活中经常会面对的问题。同学们做操时会按照从矮到高排列;老师查看上课出勤情况时,会按学生学号顺序点名;高考录取时,会按成绩总分降序依次录取等。那排序的严格定义是什么呢? 假设含有 n 个记录的序列为 ,其相应的关键字分别为 ,需确定 1,2,…… ,n 的一种排列 ,使其相应的关键字满足 ( 非递减或非递增 )关系

排序算法(三)插入排序

送分小仙女□ 提交于 2020-02-27 19:27:32
1,算法描述 算法描述: 对于未排序数据(右手抓到的牌),在已排序序列(左手已经排好序的手牌)中从后向前扫描,找到相应位置并插入。 插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 2,实现步骤 从第一个元素开始,该元素可以认为已经被排序; 取出下一个元素,在已经排序的元素序列中从后向前扫描; 如果该元素(已排序)大于新元素,将该元素移到下一位置; 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置; 将新元素插入到该位置后; 重复步骤2~5。    1)常规实现 1    /** 2 * 最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2) 3 * 最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n) 4 * 平均时间复杂度 ---- O(n^2) 5 * 所需辅助空间 ------ O(1) 6 * 稳定性 ------------ 稳定 7 */ 8 private static void insertionSort1(int[] a) { 9 long start = System.nanoTime(); 10 int len = a.length; 11 for (int i = 1;

【算法】排序(三)插入排序

帅比萌擦擦* 提交于 2020-02-27 19:27:14
上次给大家说了说简单的冒泡排序,这次我们来说一说插入排序 插入排序的做法就像是我们日常生活中玩扑克牌一样,每次抽一张牌,将扑克牌按一定顺序插入手牌中,一步步完成排序 本文将介绍以下内容 排序思想 算法实现(JAVA) 测试阶段 排序过程讲解 算法分析 排序思想 插入排序同样有内循环和外循环,外循环执行n - 1次,内循环负责比较相邻两个数的大小并交换(如果需要)。每次将未排序序列里的第一个数与后一个数比较,如果后者小,就交换二者的位置,并和以排序的序列元素依次比较并交换(如果需要)。 就如同玩扑克牌,每次抽取的一张牌都要与所有手牌一对一比较,并确定最终插入的位置。 算法实现 1. 外循环 public static void insertionSort(int[] a) { int n = a.length; for (int i = 1; i < n; i++) { } } 循环次数为n - 1,否则数组下标越界,下文会说明原因。 2. 内循环 for (int j = i; j > 0 && a[j] < a[j - 1] ; j--) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } 交换条件为后一项小于前一项,每次都是a[j]与a[j - 1] 比较,所以只能有n - 1 次循环,否则数组下标越界。 所以

算法之排序(上)

守給你的承諾、 提交于 2020-02-27 08:02:47
文章来源: http://blog.seclibs.com/算法之排序(上)/ 排序算法有很多种,甚至有很多都完全没有听过,我们最常见,也最经典的就是:冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。 按照时间复杂度来进行划分可以将其划分为三类 O(n2) :冒泡、插入、选择;基于比较 O(nlogn):快排、归并;基于比较 O(n):桶、计数、基数;不基于比较 这次我们来说时间复杂度为O(n2)的 在说具体的排序方法之前,先明确排序算法的评价标准 首先是排序算法的执行效率,执行效率一般从最好、最坏、平均时间复杂度上分析,其分析时间复杂度时需要考虑系数、常数和低阶,因为时间复杂度是在数据规模特别大的时候的增长趋势,在平时的代码中,数量级都是比较小的,所以还需要考虑这些问题。在基于比较的排序算法中,数值比较的次数和数据的移动次数也都是需要考虑进去的。 其次是内存的消耗,算法的内存消耗可以用空间复杂度来表示,当空间复杂度为O(1)的算法也可以称之为原地排序算法。 最后是算法的稳定性,当一组数据中有两个相同的值时,排序之后两个值的顺序是如果没有交换那它就是具有稳定性的算法。 然后我们再引入两个概念, 有序度 和 逆序度 有序度 是数组中具有有序关系的元素对的个数。 比如说2、4、3、1、5、6这组数组的有序度是11,因为它有11个有序元素对,分别是(2,4)

常见排序算法及其代码实现和相关问题

主宰稳场 提交于 2020-02-23 03:43:52
算法学习笔记—排序 这是最近在学习过程中整理的一部分笔记,没有图片演示,如需更生动的展示可以看这位大牛的整理博客。 排序算法的动画演示 文章目录 算法学习笔记---排序 常见的一些数组排序方法 冒泡排序 选择排序 插入排序 归并排序 快速排序 随机快速排序 堆排序 桶排序 排序方法的稳定性 比较器 递归的实质 对数器 和排序相关的经典问题 小和问题 逆序对问题 荷兰国旗问题 最大间隔问题 常见的一些数组排序方法 冒泡排序 冒泡排序的原理: 相邻位进行比较,如果满足前面的数大于后面的数,就交换前后两个数。排一个来回之后,数组中最大的数已经被移动到了最后面。 时间复杂度的分析:N+(N-1)+(N-2)+… 等差数列,O(N2) 冒泡排序的代码实现: public void bubbleSort ( int [ ] arr ) { if ( arr == null || arr . length < 2 ) { //数组为空或者数组中只有一个元素,不需要进行排序 return ; } for ( int end = arr . length - 1 ; end > 0 ; end -- ) { //使用end来标记当前比较移动操作的最后一位是多少。 //第一波比较从索引0到索引arr.length //第二波比较从索引0到索引arr.length-1 for ( int i = 0 ;