排序算法稳定性

经典排序算法--java实现

情到浓时终转凉″ 提交于 2019-11-27 14:10:47
经典排序算法--java实现 概述 算法的性能指标 时间复杂度 空间复杂度 稳定性 简单的桶排序 原理分析 代码实现 性能分析 经典的冒泡排序 原理分析 代码实现 性能分析 性能最好的快速排序 原理分析 代码实现 性能分析 换一种思路—插入排序 原理分析 代码实现 性能分析 插入排序的优化版—shell排序 原理分析 代码实现 性能分析 概述 排序算法是计算机算法里的基础概念,也是很多大厂面试的必考内容。不管你是应届毕业的小鲜肉还是浸淫技术多年的老司机,都免不了会和排序打交道。正因为大部分小伙伴平日的学习和工作中直接接触算法的几率并不大,所以时间久了以后难免生疏。正因为忘的差不多了,所以有必要把一些经典排序算法的思想和实现思路再温习一下。所谓温故而知新,总会有新的收获。 本文涉及的主要知识点: 算法的性能指标 简单的桶排序 经典的冒泡排序 性能最好的快速排序 换一种思路—插入排序 插入排序的优化版—shell排序 算法的性能指标 时间复杂度 时间复杂度是一个函数,使用O表示,一般情况下,时间复杂度由高到低的顺序是O(n 2 )>O(nlogn)>O(n)>O(logn)>O(1)。 一般如果一种算法的时间复杂度高于O(n2),那么就需要考虑是否可以寻找更优化的方案,在代码层面,一般是以循环的嵌套层次来辨别算法的时间复杂度。 比如两层循环嵌套,那么每层循环都需要执行n次,一共是n 2

排序算法--选择排序

元气小坏坏 提交于 2019-11-27 14:09:46
选择排序也是一个很简单的排序算法,我来备忘一下。。 原理 :我们仍旧选择排序一个整数组成的数组,升序排列。每次遍历数组中还没有排好序的部分,在其中选择一个最小的,放到最左边的位置,等整个数组中的元素全部放到该放的位置即停止。 步骤 :初始化遍历计数i和j,i代表每次遍历要放到最终位置的元素的下标,当然了,也代表着遍历第几次数。j就用来遍历还没有放好的部分,从中去选择一个最小的元素。需要注意的是,我们是一个个比较,但是并不是一个个交换,我们弄一个临时变量指向此次遍历中最小的元素,也记录它的值,最后交换i位置的元素和最小元素即可。 分析 :先说时间复杂度,比较的次数是n(n-1)/2,交换n次(此处也要说一下,可以遍历n-1次,最后剩下一个元素不再遍历也可以,无关大局,至于交换次数,如果是本来就升序,就不需要交换了),所以时间复杂度就是O(N^2)。关于空间,当然不需要额外的,那就是原地的了。至于稳定性,比如数组[2,2,1],第一次交换会将1和第一个2交换,那么相等元素就被变顺序了,所以它不稳定。 代码展示 : public class SelectSort { public static void main(String[] args){ int[] array = {7, 11, 5, 8, 7, 2, 10, 1}; System.out.print("待排序数组:");/

4-1 排序与搜索

陌路散爱 提交于 2019-11-27 12:33:43
排序与搜索 排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。 排序算法的稳定性 稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。 当相等的元素是无法分辨的,比如像是整数,稳定性并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。 (4, 1) (3, 1) (3, 7)(5, 6) 在这个状况下,有可能产生两种不同的结果,一个是让相等键值的纪录维持相对的次序,而另外一个则没有: (3, 1) (3, 7) (4, 1) (5, 6) (维持次序) (3, 7) (3, 1) (4, 1) (5, 6) (次序被改变) 不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地实现为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个对象间之比较,(比如上面的比较中加入第二个标准:第二个键值的大小)就会被决定使用在原先数据次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。 来源: https://www.cnblogs.com/echo-kid-coding/p

C/C++实现排序算法(持续更新~~~~~~)

我与影子孤独终老i 提交于 2019-11-27 07:12:54
github: https://github.com/xiaozhengwei/Algorithms-And-DataStructure /** * 冒泡排序 * 时间复杂度(平均) : O(n²) * 时间复杂度(最好) : O(n) * 时间复杂度(最坏) : O(n²) * 空间复杂度 : O(1) * 稳定性: : 稳定 * @param arr : 标记数组首地址的指针 * @param length : 数组长度 * @param type : 排序类型 * @param state : 若数组不再发生变化,则表示已经排序成功,停止排序 * 为0从小到大 * 非0从大到小 */ void bubbleSort(int *arr, int length, int type) { if (length < 2) return; int state = 1;//标记状态,若数组没有发生变化,则停止排序 for (int i = 0; i < length - 1; i++){ for (int j = 0; j < length - i - 1; j++){ if (type ? arr[j] < arr[j + 1] : arr[j] > arr[j + 1]) { arr[j] = arr[j] ^ arr[j + 1]; arr[j + 1] = arr[j] ^

数据结构之排序五:选择排序

江枫思渺然 提交于 2019-11-27 03:14:54
def selectedSort(myList): #获取list的长度 length = len(myList) #一共进行多少轮比较 for i in range(0,length-1): #默认设置最小值得index为当前值 smallest = i #用当先最小index的值分别与后面的值进行比较,以便获取最小index for j in range(i+1,length): #如果找到比当前值小的index,则进行两值交换 if myList[j]<myList[smallest]: smallest = j tmp = myList[smallest] myList[smallest] = myList[i] myList[i]=tmp # 打印每一轮比较好的列表 print("Round ",i,": ",myList) 时间复杂度::   平均:O(n^2)   最坏:O(n^2)   最好:O(n^2) 空间复杂度:O(1) 稳定性:不稳定(三个简单排序中唯一一个不稳定的算法,也是最好最坏情况一样复杂的一个,其他两个最优情况都是O(n)) 来源: https://www.cnblogs.com/mengxiangtiankongfenwailan/p/11341093.html

常用排序算法

血红的双手。 提交于 2019-11-27 02:54:45
笔者最近学习算法,学了很久也只弄懂了几个排序算法,在这里晒一下下,作为以后参考之用。 一、 为什么要研究排序问题 许多计算机科学家认为,排序算法是算法学习中最基本的问题,原因有以下几点: l 有时候应用程序本身需要对信息进行排序,如为了准备客户账目,银行需要对支票账号进行排序 l 很多算法将排序作为关键子程序 l 现在已经有很多排序算法,它们采用各种技术 l 排序时一个可以证明其非平凡下界的问题,并可以利用排序问题的下界证明其他问题的下界 l 在实现排序算法是很多工程问题即浮出水面 二、 排序问题的形式化定义 输入:由 n 个数组成的一个序列 <a 1 ,a 2 , …… ,a n > 输出:对输入序列的一个排列(重排) <a 1 ’,a 2 ’, …… ,a n ’>, 使得 a 1 ’ ≤ a 2 ’ ≤……≤ a n ’ 【说明】在实际中,待排序的数很少是孤立的值,它们通常是成为激励的数据集的一个部分,每个记录有一个关键字 key, 是待排序的值,其他数据位卫星数据,它们通常以 key 为中心传递。 三、 相关概念 1. 排序的稳定性: 在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则称这种排序方法是不稳定的。 A. 稳定排序: 插入排序 、冒泡排序

选择排序

百般思念 提交于 2019-11-27 02:54:26
/*--> */ /*--> */ 算法思想 从左到右依次比较,找出全部无序最小的元素与数组中的第一个元素进行交换;然后从第数组中第二个元素 开始比较,找出剩余无序元素中最小的的元素,然后将其与数组中的第二个元素进行交换,按照这种方式操作 下去直到数组有序 例:升序排序8,1,6,3,2,4 代码实现 bool SelectionSort(int *pAry, int nSize) { if (pAry == nullptr || nSize <= 0) { return false; } for (int iIndex = 0; iIndex < nSize-1; iIndex++) { int nIndexOfMinValue = iIndex; for (int jIndex = iIndex+1; jIndex < nSize; jIndex++) { if (pAry[nIndexOfMinValue] > pAry[jIndex]) { nIndexOfMinValue = jIndex; } } if (nIndexOfMinValue != iIndex) { int nTemp = pAry[nIndexOfMinValue]; pAry[nIndexOfMinValue] = pAry[iIndex]; pAry[iIndex] = nTemp; } }

冒泡排序

雨燕双飞 提交于 2019-11-27 02:14:25
/*--> */ /*--> */ 算法思路 升序排列: 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素大(或者小),就交换他们两个。 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元 素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成 降序排列: 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素小(或者大),就交换他们两个。 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元 素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成 例:使冒泡法升序排列8,1,6,3,2,4 从左到右进行排序: 第一轮: 第二轮: 第三轮: 第四轮: 本轮中没有发生元素交换,就表示剩下的元素都是有序的,所以所有元素已经都是有序的了。 代码实现 bool BubbleSort(int * pUnSortAry, int nArySize) { if (pUnSortAry == nullptr || nArySize <= 0) { return false; } bool bFlag = false; for

经典排序方法 python

孤者浪人 提交于 2019-11-26 17:57:01
  数据的排序是在解决实际问题时经常用到的步骤,也是数据结构的考点之一,下面介绍10种经典的排序方法。   首先,排序方法可以大体分为插入排序、选择排序、交换排序、归并排序和桶排序四大类,其中,插入排序又分为直接插入排序、二分插入排序和希尔排序,选择排序分为直接选择排序和堆排序,交换排序分为冒泡排序和快速排序,桶排序以基数排序和计数排序为代表。这些排序方法的时间复杂度和空间复杂度分别如下表所示。   排序方法的稳定性是这样定义的:在待排序序列中如果存在a[i]和a[j],a[i]=a[j]&&i<j,如果排序后仍然符合a[i]=a[j]&&i<j,即它们的前后相对位置关系没有改变,该排序算法就是稳定的。   (1)直接插入排序   插入排序的基本思想是将数据插入合适的位置。如下所示序列[6,8,1,4,3,9,5,0],以升序排列为例。   a.6<8,符合升序   b. 8>1,不符合要求,改变1的位置。首先比较1和8,1更小,交换1和8的位置,序列成为[6,1,8,4,3,9,5,0],然后继续比较1和6,1更小,交换1和6的位置,序列成为[1,6,8,4,3,9,5,0],注意此时前三个值已经符合升序的要求。   c. 8>4,不符合要求,改变4的位置,按照上面的方法,依次与前面的值比较,分别与8和6交换位置,当比较到1时,1<4,不用交换位置。此时序列成为[1,4,6,8

桶排序

为君一笑 提交于 2019-11-26 17:51:52
排序算法中最快、最简单的排序算法,及其耗费内存。 原理 把同类元素放在相同的桶里,每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序),桶本身是有序的! 1、确定桶的数量; 2、遍历列表,把元素放到对应的桶里; 3、重复2; 4、把排序好的元素放回原列表,知道排序完成; 分析 平均:T(n)=o(n) 当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间 O (n)。 空间复杂度为 O (n+m)。 桶排序的稳定性依赖于桶内排序。如果我们使用了快排,显然,算法是不稳定的。 代码 来源: https://www.cnblogs.com/pacino12134/p/11329751.html