排序算法

14.排序算法---选择排序

守給你的承諾、 提交于 2020-03-06 09:02:27
基本介绍: 选择式排序也属于内部排序法,是从预排序的数据中,按指定的规则 选出某一元素 ,再依规定交换位置后达到排序的目的。 选择排序思想: 选择排序(select sorting)也是一种简单的排序方法。它的 基本思想是 :第一次从arr[0]–arr[n-1]中选取最小值,与arr[0]交换,第二次从arr[1]–arr[n-1]中选取最小值,与arr[1]交换,第三次从arr[2]–arr[n-1]中选取最小值,与arr[2]交换,…,第i次从arr[i-1]–arr[n-1]中选取最小值,与arr[i-1]交换,…, 第n-1次从arr[n-2]~arr[n-1]中选取最小值,与arr[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。 //选择排序 public static void selectSort ( int [ ] arr ) { //在下面的逐步推导的方式的过程,我们发现了规律,因此,可以使用for来解决 //选择排序时间复杂度是 O(n^2) for ( int i = 0 ; i < arr . length - 1 ; i ++ ) { int minIndex = i ; int min = arr [ i ] ; for ( int j = i + 1 ; j < arr . length ; j ++ ) { if (

八大排序(三)-------快速排序

蹲街弑〆低调 提交于 2020-03-06 08:59:47
快速排序法介绍: 快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 感觉自己能力并不足以将一个问题,或算法讲解的足够清楚,只是在别人的基础上理解,明白了代码的含义,知道了执行的流程,知道了原理,但是要我自己讲述,或者深入的说出其底层原理,做不来 所以很多内容粗糙且模糊,见谅 所以这下面的是我参考的别人的讲解,来源忘了 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。 3 1 2 5 4 6 9 7 10 8 在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。想一想,你有办法可以做到这点吗? 给你一个提示吧。请回忆一下冒泡排序,是如何通过“交换”

数据结构与算法 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 ] ,

排序算法的步步解析

眉间皱痕 提交于 2020-03-06 00:07:14
总结镇楼:只讲自己的细节 1.冒泡排序:比较两个相邻的元素,将值大的元素交换到右边 代码如下:核心思想:第二次循环中数组元素的两两比较,再重复这个循环数组长度次 public static int[] maopao(int[] arrs){ int length=arrs.length; int temp; if(length==0){ return arrs; } //第一个循环是让比较的遍数进行到“数组长度次” for (int i=0;i<length;i++) { /*/ 冒泡排序的两两比较具体步骤只需用一个循环,因为最佳的状况时其时间复杂度为n 这里需要注意的是第二个循环的长度,冒泡排序发每次循环都会得出一个数组中剩余数的最大值放到后面 因此每次循环都会使循环的次数减一,而最多经历数组长度次的循环之后整个数组就会排序完毕 */ for (int j=0;j<length-1-i;j++){ //简单的三方转换 if (arrs[j]>arrs[j+1]){ temp=arrs[j+1]; arrs[j+1]=arrs[j]; arrs[j]=temp; } } } return arrs; } ----------------------------------------------- 2.选择排序:从头到尾扫描一遍数组,将其中的最小值放到最前面,

【数据结构与算法之美】排序优化:如何实现一个通用的、高性能的排序函数?

我与影子孤独终老i 提交于 2020-03-05 22:04:21
目录 一、如何选择合适的排序算法? 1.排序算法一览表 2.为什选择快速排序? 二、如何优化快速排序? 三、通用排序函数实现技巧 四、课后思考 一、如何选择合适的排序算法? 1.排序算法一览表 时间复杂度 是稳定排序? 是原地排序? 冒泡排序 O(n^2) 是 是 插入排序 O(n^2) 是 是 选择排序 O(n^2) 否 是 快速排序 O(nlogn) 否 是 归并排序 O(nlogn) 是 否 桶排序 O(n) 是 否 计数排序 O(n+k),k是数据范围 是 否 基数排序 O(dn),d是纬度 是 否 2.为什选择快速排序? 1)线性排序时间复杂度很低但使用场景特殊,如果要写一个通用排序函数,不能选择线性排序。 2)为了兼顾任意规模数据的排序,一般会首选时间复杂度为O(nlogn)的排序算法来实现排序函数。 3)同为O(nlogn)的快排和归并排序相比,归并排序不是原地排序算法,所以最优的选择是快排。 二、如何优化快速排序? 导致快排时间复杂度降为O(n)的原因是分区点选择不合理,最理想的分区点是:被分区点分开的两个分区中,数据的数量差不多。如何优化分区点的选择?有2种常用方法,如下: 1.三数取中法 ①从区间的首、中、尾分别取一个数,然后比较大小,取中间值作为分区点。 ②如果要排序的数组比较大,那“三数取中”可能就不够用了,可能要“5数取中”或者“10数取中”。 2.随机法

【LintCode 题解】谷歌面试算法题:两个排序数组的中位数

点点圈 提交于 2020-03-05 21:09:31
题目描述 两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。 说明 中位数的定义: 这里的 中位数 等同于数学定义里的 中位数 。 中位数是排序后数组的中间值。 如果有数组中有n个数且n是奇数,则中位数为A[(n-1)/2]A[(n−1)/2]。 如果有数组中有n个数且n是偶数,则中位数为 (A[n / 2] + A[n / 2 + 1]) / 2(A[n/2]+A[n/2+1])/2. 比如:数组A=[1,2,3]的中位数是2,数组A=[1,19]的中位数是10。 样例1 输入: A = [1,2,3,4,5,6] B = [2,3,4,5] 输出: 3.5 样例2 输入: A = [1,2,3] B = [4,5] 输出: 3 题解 分治法。时间复杂度 log(n + m)log(n+m) 这题是 面试高频题 ,除了分治法外,还有二分法等其他方法来解, 算法面试高频题班 免费试听,攻略还有更多大厂常考题型。 public class Solution { public double findMedianSortedArrays(int A[], int B[]) { int n = A.length + B.length; if (n % 2 == 0) { return ( findKth(A, 0, B, 0, n

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); • 在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数

java中级,知识点归纳(一)

社会主义新天地 提交于 2020-03-05 12:25:34
一、接口和抽象类的区别 抽象类中可以含有构造方法,而接口内不能有。 抽象类中可以有普通成员变量,而接口中不能有。 抽象类中可以包含非抽象的普通方法,而接口中所有方法必须是抽象的,不能有非抽象的普通方法。 抽象类中的抽象方法的访问类型可以是public、protected和默认类型,但接口中的抽象方法只有public和默认类型。 抽象类中可以包含静态方法,接口内不能包含静态方法。 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以是任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。 一个类可以实现多个接口,但只能继承一个抽象类。 接口更多的是在系统框架设计方法发挥作用,主要定义模块之间的通信,而抽象类在代码实现方面发挥作用,可以实现代码重用。 二、java虚拟机的运行时数据区有几块?线程私有和线程共享区域有哪些? 程序计数器:线程私有,当前线程执行的字节码的行号指示器。 虚拟机栈:线程私有,存放基本数据类型、对象引用和returnAddress类型。 本地方法栈:为虚拟机使用到的Native方法服务。 java堆:线程共享,存放对象的实例,也是GC回收器管理的主要区域。 方法区:线程共享,存放已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。 运行时常量池:方法区的一部分

选择排序、插入排序、冒泡排序、希尔排序

六月ゝ 毕业季﹏ 提交于 2020-03-05 03:14:38
简介 以下总结几个基础的排序算法,包括选择排序、插入排序、冒泡排序、希尔排序,这几个排序算法是比较简单的几个。以下给出算法的分析和代码示例。 时间复杂度 选择排序、插入排序、冒泡排序、希尔排序四个排序算法的时间复杂度都是O(n^2)。 算法分析 选择排序 选择排序取第一个元素以此与后续的元素进行比较,保存最小的元素的下标,最终把最小的元素与第一个元素进行交换,第二次遍历取第二个元素,在剩余元素中选择最小的元素与第二个元素交换,依次类推。。。。,最终实现把所有元素按照从小到大进行排序。 以下为代码示例 template<typename T> void selectionSort(T arr[], int n){ for(int i = 0 ; i < n ; i ++){ int minIndex = i; for( int j = i + 1 ; j < n ; j ++ ) if( arr[j] < arr[minIndex] ) minIndex = j; swap( arr[i] , arr[minIndex] ); } } 选择排序是基础的排序算法,但需要重点理解,以后复杂的算法也都会以此为基础进行衍生。 插入排序 插入排序分为两种,第一种是直接插入排序,第二种是折半插入排序,以下分别描述两种排序的基本思想: 直接插入排序的基本思想: 当插入第i(i>1)个元素时