排序算法稳定性

六种常见排序算法(Python语言实现)

半世苍凉 提交于 2019-12-12 23:28:37
文章目录 排序算法总结 常见算法时间复杂度比较 冒泡排序 简介与工作原理: 代码实现 选择排序 插入排序 快速排序 希尔排序 归并排序 排序算法总结 常见算法时间复杂度比较 冒泡排序 简介与工作原理: 简介:是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 从第一个元素开始,与相邻的元素进行比较,如果比较结果是升序的,就把这两个元素进行互换 从第一对到最后一对进行比较,对每一对相邻元素重复进行此操作,做完这个操作后,最后一个元素是最大的元素 针对所以的元素再重复以上步骤 持续对越来越少的元素进行以上的步骤,直到没有任何一对数据需要比较为止。 代码实现 #!/usr/local/bin/python 2 # 冒泡排序 3 def bubb_sort ( list ) : 4 L = len ( list ) 5 for j in range ( L , 0 , - 1 ) : 6 for i in range ( j - 1 ) : 7 if list [ i ] > list [ i + 1 ] : 8 list [ i ] , list [ i + 1 ] = list [ i + 1

第八章排序(1)

不羁的心 提交于 2019-12-12 10:41:24
排序的基本概念 排序:给定一组记录的集合{r1, r2, ……, rn},其相应的关键码分别为{k1, k2, ……, kn},排序是将这些记录排列成顺序为{rs1, rs2, ……, rsn}的一个序列,使得相应的关键码满足ks1≤ks2≤……≤ksn(称为升序)或ks1≥ks2≥……≥ksn(称为降序)。 正序:待排序序列中的记录已按关键码排好序。 逆序(反序):待排序序列中记录的排列顺序与排好序的顺序正好相反。 趟:在排序过程中,将待排序的记录序列扫描一遍称为一趟。通常,一次排序过程需要进行多趟扫描才能完成 排序算法的稳定性: 假定在待排序的记录集中,存在多个具有相同键值的记录,若经过排序,这些记录的相对次序仍然保持不变,即在原序列中,ki=kj且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。 排序算法的稳定性 对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而证明稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的。不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。 算法的稳定性与算法的具体实现有关 冒泡排序是稳定的排序方法 5,3,3,4 如果规则是 A[i]>a[i+1],则是稳定 如果规则是A[i]>=a[i

第九章:内部排序

被刻印的时光 ゝ 提交于 2019-12-10 21:59:13
排序:将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。 稳定性——若两个记录A和B的关键字值相等,且排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。 1.插入排序 思想:每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。 简言之,边插入边排序,保证子序列中随时都是排好序的。 1) 直接插入排序 在已形成的有序表中线性查找,并在适当位置插入,把原来位置上的元素向后顺移 时间效率: 因为在最坏情况下,所有元素的比较次数总和为(0+1+…+n-1)→O(n^2)。 其他情况下也要考虑移动元素的次数。 故时间复杂度为O(n^2) 空间效率:仅占用1个缓冲单元——O(1) 算法的稳定性:稳定 直接插入排序算法的实现: void InsertSort ( SqList &L ) { //对顺序表L作直接插入排序 for ( i = 2; i <=L.length; i++) //假定第一个记录有序 { L.r[0]= L.r[i]; j=i-1 ; //先将待插入的元素放入“哨兵”位置 while(L[0] .key<L[j].key) { L.r[j+1]= L.r[j]; j-- ; } //只要子表元素比哨兵大就不断后移 L.r[j+1]= L.r[0]; //直到子表元素小于哨兵,将哨兵值送入 /

数据结构之排序算法(八大排序)-(八)

坚强是说给别人听的谎言 提交于 2019-12-07 22:08:40
排序算法可以分为稳定排序和不稳定排序。在简单形式化一下,如果A[i] = A[j],A[i]原来在位置前,排序后A[i]还是要在A[j]位置前,这才能叫稳定排序。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。另外,如果排序算法稳定,对基于比较的排序算法而言,元素交换的次数可能会少一些(个人感觉,没有证实)。 回到主题,现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。 (1)冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。 (2)选择排序 选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面

【数据结构】排序算法时间效率、空间效率以及算法稳定性总结

心不动则不痛 提交于 2019-12-07 22:08:29
排序算法   排序是将一组无序的记录序列调整为有序的记录序列的操作,可以方便查找。大部分的排序算法都有两个基本的操作:(1)比较两个关键字的大小.(2)将记录从一个位置移动到另一个位置。 排序算法分类   根据完成整个排序过程是否需要访问外存可分为内部排序、外部排序。一般进行的是内部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。基于不同的扩大有序序列的方法,内部排序大致可以分为插入排序、快速排序、选择排序、归并排序。 方法 思想 分类 插入排序 每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。 直接插入排序、折半插入排序、表插入排序、希尔排序 交换排序 比较序列中的记录,并按前小后大(或前大后小)的规则对记录进行交换 冒泡排序、一趟快速排序、 快速排序 选择排序 从无序序列中选出关键字最小的记录,加入到有序序列 简单选择排序、树型选择排序、 堆排序 归并排序 将两个或两个以上的有序序列归并为一个有序性序列 2-路归并排序 排序算法的效率评价   排序算法的好坏一般从时间效率、空间效率、稳定性三个方面衡量。  (1)时间效率指排序速度,即排序所花费的全部比较次数。  (2)空间效率指占内存辅助空间的大小。  (3)稳定性是相同关键字值在排序前后的先后次序是否保持一致。若两个记录A和B的关键字值相等,但排序后A

数据结构--排序算法总结

拥有回忆 提交于 2019-12-07 22:04:26
原创不易,尊重原创,本文转载于 Nim的辙迹 的博文,博文地址:http://blog.csdn.net/codernim/article/details/54312616 概述 排序的分类:内部排序和外部排序 内部排序:数据记录在内存中进行排序 外部排序:因排序的数据量大,需要内存和外存结合使用进行排序 这里总结的八大排序是属于内部排序: 当n比较大的时候, 应采用时间复杂度为( nlog 2 n )的排序 算法 :快速排序、堆排序或归并排序。 其中,快速排序是目前基于比较的内部排序中被认为最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短。 ——————————————————————————————————————————————————————————————————————— 插入排序——直接插入排序( Straight Insertion Sort ) 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新的,记录数增1的有序表。 即:先将序列的第1个记录看成一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。 要点:设立哨兵,用于临时存储和判断数组边界 直接插入排序示例: 插入排序是稳定的 ,因为如果一个带插入的元素和已插入元素相等,那么待插入元素将放在相等元素的后边,所以,相等元素的前后顺序没有改变。 算法实现: [cpp]

八大排序算法

妖精的绣舞 提交于 2019-12-07 22:03:57
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。 本文将依次介绍上述八大排序算法。 算法一:插入排序 插入排序示意图 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 算法步骤 : 1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) 代码实现: void insert_sort(int array[],unsignedint n) { int i,j; int temp; for(i = 1;i < n;i++) { temp = array[i]; for(j = i;j > 0&& array[j - 1] > temp;j--) { array[j]= array[j - 1]; } array[j] = temp; } } 算法二:希尔排序 希尔排序示意图 希尔排序 ,也称

数据结构之排序算法

痞子三分冷 提交于 2019-12-07 22:01:12
作者:离散梦 欢迎大家给出宝贵的建议! 数据结构之排序算法 稳定排序 :冒泡、插入、归并、基数 不稳定排序 :选择、快速、希尔、堆 口诀就是: 快 (快速) 些 (希尔) 选 (选择) 一 堆 (堆) 好朋友来玩吧! 1.冒泡排序 冒泡排序(Bubble Sort)一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。【时间复杂度为O(n^2),最好的情况就是有序的时候为O(n)】 算法思想过程: 冒泡排序算法——python实现程序 2.选择排序 选择排序(Selection Sort )就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。【时间复杂度为O(n^2)】 算法思想过程: 选择排序算法——python实现程序 3.插入排序 插入排序(Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。【时间复杂度为O(n^2),最好的情况是排好序的时候为O(n)】 算法思想过程: 注:下面排序之后答案是1,2,3,4,5,6,7,8.我下面这幅图有些许错误,就不重新作图了。 插入排序算法——python实现程序 4.归并排序 归并排序(Merging Sort)就是利用归并的思想实现的排序方法

开发中常见的算法汇总一览

心已入冬 提交于 2019-12-07 22:00:39
我们知道计算机中各类应用程序随处可见的,而支撑这些应用程序运行的就是各类数据结构以及各类算法,这就是经典等式 程序=数据结构+算法 ,上一篇幅中我们列举了一些常用的数据结构,那么今天我们来捋一捋日常开发中常见的一些算法思想以及具体算法各自的特性及相关指标 文章目录 常见算法思想 穷举法(Brute Force) 核心思想 特性 适用问题或算法 分治法(Divide and Conquer) 核心思想 特性 适用问题或算法 贪心算法(Greedy) 核心思想 特性 适用问题或算法 动态规划法(Dynamic Programming) 核心思想 特性 适用问题或算法 回溯法(Backtracking) 核心思想 特性 适用问题或算法 分枝界限法(Branch and Bound) 关于递归(画外音) 贪心和动态规划(画外音) 常见的算法分类 排序算法 冒泡排序 插入排序 希尔排序 选择排序 归并排序 快速排序 堆排序 计数排序 桶排序 基数排序 排序算法总结 查找算法 顺序查找 二分查找 散列查找 二叉树查找 搜索算法 树的层次遍历 树的(前/中/后)序遍历 常见算法思想 我们首先介绍下几种常见的算法思想,日常中一些具体的解题算法的思想都依赖于它们,文中列举一些具体算法问题可以自行通过搜索引擎了解 穷举法(Brute Force) 核心思想 顾名思义就是列举出所有可能出现的情况

排序算法:直接插入排序

北战南征 提交于 2019-12-06 22:28:09
直接插入排序是一种最简单的 插入排序 。 插入排序 :每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,知道全部插入完成。 在讲解直接插入排序之前,先让我们脑补一下我们打牌的过程。 先拿一张5在手里, 再摸到一张4,比5小,插到5前面, 摸到一张6,嗯,比5大,插到5后面, 摸到一张8,比6大,插到6后面, 。。。 最后一看,我靠,凑到全是同花顺,这下牛逼大了。 以上的过程,其实就是典型的 直接插入排序,每次将一个新数据插入到有序队列中的合适位置里。 很简单吧,接下来,我们要将这个算法转化为编程语言。 假设有一组无序序列 R0, R1, … , RN-1。 (1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。 (2) 然后,我们要依次把 R1, R2, … , RN-1 插入到这个有序序列中。所以,我们需要一个 外部循环 ,从下标 1 扫描到 N-1 。 (3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。 所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个 内部循环 ,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。 核心代码 public void insertSort(int[] list)