排序算法稳定性

排序(python)

我的未来我决定 提交于 2019-12-28 05:03:52
1 # 冒泡算法:是一种简单排序,重复的遍历要排序的数列,一次比较两种元素,如果顺序错误,就交换两者的位置,重复的的进行知道没有在需要交换 2 # 步骤如下: 3 # 冒泡排序算法的运作如下: 4 # 第一次进行遍历,进行n-1次两两比较,将最大(小)的元素,进行放入最后一位,下一次,对前n-2的元素进行两两进行比较.放入最后第二位.... 5 # 时间复杂度为:(稳定) 6 # 最小为o(n),即该序列的有序的序列,最大为o(n),即,第一次要n-1,n-2,n-3...即最大为o(n^2) 7 import random 8 def produce_num(n): 9 return_nums=[] 10 for i in range(n): 11 num=random.randint(1,n) 12 return_nums.append(num) 13 return return_nums 14 def bubble_sort_high(list_): 15 # 进行升序排序 16 # 控制循环轮数 17 for i in range(len(list_)-1): 18 # 每一次遍历,两两比较,得到最大(小)的元素放入,当前循环长度的最后一位 19 for j in range(len(list_)-i-1): 20 # 如果取出的元素大于剩余的元素,则进行交换元素 21

排序问题之快速排序

ぐ巨炮叔叔 提交于 2019-12-28 04:10:56
排序问题 算法问题的基础问题之一,便是排序问题:   输入:n个数的一个序列,<a 1 , a 2 ,..., a n >。   输出:一个排列<a 1 ' ,a 2 ' , ... , a n' >,满足a 1 ' ≤ a 2 ' ≤... ≤ a n' 。(输出亦可为降序,左边给出的例子为升序) 一.算法描述 (1) 分治法 快速排序 使用到了分治方法(Divide and Conquer)。   Divide:将原问题分解为若干子问题,其中这些子问题的规模小于原问题的规模。   Conquer:递归地求解子问题,当子问题规模足够小时直接求解。   Merge:将子问题的解合并得到原问题的解。  (2) 快速排序的分治思想 分解: 分解待排序的n个元素序列A[p, ... q]为A[p, ... , r-1],A[r],A[r+1, ... , q],使得A[p, ... , r-1]中的所有元素都小于A[r],A[r+1, ... , q]中的所有元素都大于A[r]   解决: 递归地调用快速排序,对两个子序列A[p, ... , r-1]、A[r+1, ... , q]进行快速排序   合并: 因为子序列都是按原址排序的,不需要进行合并操作  (3) 快速排序 Partition(A, p, q): 假设我们要对一个输入规模为n的序列A[p,p+1, ... , q

快速排序算法原理及实现(单轴快速排序、三向切分快速排序、双轴快速排序)

情到浓时终转凉″ 提交于 2019-12-28 04:10:46
1. 工作原理(定义)   快速排序(Quicksort)是对冒泡排序的一种改进。(分治法策略)   快速排序的基本思想是在待排序的n个记录中任取一个记录(通常取第一个记录)作为基准,把该记录放入适当位置后,数据序列被此记录划分成两部分,分别是比基准小和比基准大的记录;然后再对基准两边的序列用同样的策略,分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。    2. 算法步骤   实现方法两种方法:挖坑法和指针交换法   基准的选择三种方法:1.选择最左边记录 2.随机选择 3.选择平均值 2.1 挖坑法 设置两个变量i、j,排序开始的时候:i=0,j=N-1; 以第一个数组元素作为关键数据,赋值给key,即key=A[0]; 从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]的值交换; 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]的值交换; 重复第3、4步,直到i=j;   【3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束】。

[数据结构]快速排序

南笙酒味 提交于 2019-12-28 04:09:46
算法思想   快速排序是对冒泡排序的一种改进。其基本思想是基于分治法的;在待排序表L[1….n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1….k1]中所有元素小于pivot,L[k+1….n]中所有元素大于或等于pivot,则pivot放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置上。   首先假设划分算法已知,记为Partition(),返回的是上述中的k,注意到L(k)已经在最终的位置,所以可以先对表进行划分,而后对两个表调用同样的排序操作。因此可以递归地调用快速排序算法进行排序,具体的程序结构如下介绍。 算法代码 void QuickSort(ElemTpye A[],int low,int high){ if(low<high){ //Partition()就是划分操作,将表A[low...high]划分为满足上述条件的两个子表 int pivotpos=Partition(A,low,high);//划分 QuickSort(A,low,pivotpos-1);//依次对两个子表进行递归排序 QuickSort(A,pivotpos+1,high); } }  

我的Java开发学习之旅------>Java经典排序算法之归并排序

非 Y 不嫁゛ 提交于 2019-12-28 04:06:24
一、归并排序 归并 排序 是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并 。 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。 二、 归并操作 三、两路归并算法 1、算法基本思路  设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 (1)合并过程  合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字

我的Java开发学习之旅------>Java经典排序算法之归并排序

爱⌒轻易说出口 提交于 2019-12-28 04:06:11
一、归并排序 归并 排序 是建立在归并操作上的一种有效的排序算法,该算法是採用分治法(Divide and Conquer)的一个很典型的应用。将已有序的子序列合并,得到全然有序的序列。即先使每一个子序列有序。再使子序列段间有序。若将两个有序表合并成一个有序表。称为二路 归并 。 归并过程为:比較a[i]和a[j]的大小。若a[i]≤a[j],则将第一个有序表中的元素a[i]拷贝到r[k]中,并令i和k分别加上1。否则将第二个有序表中的元素a[j]拷贝到r[k]中,并令j和k分别加上1。如此循环下去。直到当中一个有序表取完,然后再将还有一个有序表中剩余的元素拷贝到r中从下标k到下标t的单元。归并排序的算法我们通经常使用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。 二、 归并操作 三、两路归并算法 1、算法基本思路  设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high]。先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完毕后将R1复制回R[low..high]中。 (1)合并过程  合并过程中,设置i,j和p三个指针。其初值分别指向这三个记录区的起始位置。 合并时依次比較R[i]和R[j]的keyword

我的Java开发学习之旅------>Java经典排序算法之归并排序

江枫思渺然 提交于 2019-12-28 04:05:56
一、归并排序 归并 排序 是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并 。 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。 二、 归并操作 三、两路归并算法 1、算法基本思路  设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 (1)合并过程  合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字

Java常见排序算法之归并排序

大憨熊 提交于 2019-12-28 04:04:24
在学习算法的过程中,我们难免会接触很多和排序相关的算法。总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的。 从今天开始,我们将要进行基本的排序算法的讲解。Are you ready?Let‘s go~~~ 1、 排序算法的基本概念的讲解 时间复杂度:需要排序的的关键字的比较次数和相应的移动的次数。 空间复杂度:分析需要多少辅助的内存。 稳定性:如果记录两个关键字的A和B它们的值相等,经过排序后它们相对的位置没有发生交换,那么我们称这个排序算法是稳定的。 否则我们称这个排序算法是不稳定的。 排序算法的常见分类: 1、内部排序(最常见的一种排序方式,不需要借助第三方辅助存储工具) 2、外部排序(需要借助外部存储来辅助完成相关的排序操作) 如果参与排序的数据元素非常的多,数据量非常的大,计算机无法把整个排序过程放到内存中进行的话, 我们必须借助外部存储器如磁盘来完成,这种排序方式,我们称之为外部排序。 其中外部排序最常见的就是多路归并排序,即将原始文件分解成多个能够一次性装入内存的部分,分别把每一部分调入 内存完成相应的排序,接下来在对多个有序的外部文件进行多路归并排序。 对于我们绝大多数的程序员而言,我们经常遇到的为内部排序。接下来我们将要对常见的内部排序进行相应的讲解。 今天要讲解的内部排序为: 归并排序 1.归并排序的基本概念的讲解

python 归并排序

不羁的心 提交于 2019-12-28 04:04:00
归并排序 仍然是利用完全二叉树实现,它是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。 基本过程 :假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列,再两两归并,最终得到一个长度为n的有序序列为止,这称为2路归并排序。 下面的截图来自《大话数据结构》相关章节,便于理解整个代码的实现过程。 图中主要表明了实例代码中的两部分,分别为原始序列的拆分和合并两部分。 下面是实例代码: # -*- coding:utf-8 -*- __author__ = 'webber' import random, time def merge_sort(lst): if len(lst) <= 1: return lst # 从递归中返回长度为1的序列 middle = len(lst) / 2 left = merge_sort(lst[:middle]) # 通过不断递归,将原始序列拆分成n个小序列 right = merge_sort(lst[middle:]) return merge(left, right) def merge(left, right): i, j = 0, 0 result = []

007-排序算法-堆排序

不羁的心 提交于 2019-12-28 04:01:10
一、概述   堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 排序方法 时间复杂度(平均) 时间复杂度 (最坏) 时间复杂度(最好) 空间复杂度 稳定性 堆排序 $O(nlogn)$ O(nlogn) O(nlogn) O(1) 不稳定   在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作: 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点 创建最大堆(Build Max Heap):将堆中的所有数据重新排序 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 1.1、说明      不断将大根堆的堆顶元素与堆尾元素交换,再重建大根堆的过程。将待排序列构建成大根堆,用变量 heapSize 来控制堆的大小,然后不断地 heapify ,直到 heapSize 等于零。在 heapify 的过程中就是先比较子节点的大小,然后比较父节点和子节点的大小,如果最后发现父节点是比子节点大的话跳出 heapify 循环,否则将子节点与父节点交换,并且找到子节点的左孩子,再重复上诉过程,直到左孩子的位置 left 大于