8大排序算法

合集下载

十大经典排序算法总结

十大经典排序算法总结

⼗⼤经典排序算法总结

最近⼏天在研究算法,将⼏种排序算法整理了⼀下,便于对这些排序算法进⾏⽐较,若有错误的地⽅,还请⼤家指正

0、排序算法说明

0.1 排序术语

稳定:如果a=b,且a原本排在b前⾯,排序之后a仍排在b的前⾯

不稳定:如果a=b,且a原本排在b前⾯,排序之后排在b的后⾯

时间复杂度:⼀个算法执⾏所耗费的时间

空间复杂度:⼀个算法执⾏完所需内存的⼤⼩

内排序:所有排序操作都在内存中完成

外排序:由于数据太⼤,因此把数据放在磁盘中,⽽排序通过磁盘和内存的数据传输才能进⾏

0.2算法时间复杂度、空间复杂度⽐较

0.3名词解释

n:数据规模

k:桶的个数

In-place:占⽤常数内存,不占⽤额外内存

Out-place:占⽤额外内存

0.4算法分类

1.冒泡排序

冒泡排序是⼀种简单的排序算法。它重复地⾛访过要排序的数列,⼀次⽐较两个元素,如果它们的顺序错误就把它们交换过来。⾛访数列的⼯作是重复地进⾏直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越⼩的元素会经由交换慢慢“浮”到数列的顶端

1.1算法描述

⽐较相邻的元素,如果前⼀个⽐后⼀个打,就交换

对每⼀对相邻元素做同样的⼯作,从开始第⼀对到结尾最后⼀对,这样在最后的元素应该会是最⼤的数

针对所有的元素重复以上的步骤,除了最后⼀个

重复步骤1-3,知道排序完成

1.2动图演⽰

1.3代码实现

public static int[] bubbleSort(int[] array) {

if (array.length == 0)

return array;

10种常用典型算法

10种常用典型算法

10种常用典型算法

1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法。它通过依次比较相邻的两个元素,如果顺序不对则交换位置。这样,每一趟排序都会将最大的元素移动到末尾。通过多次重复这个过程,直到所有元素按照升序排列为止。

2. 选择排序(Selection Sort)

选择排序也是一种简单的排序算法。它通过每次从未排序的部分中选出最小的元素,放到已排序部分的末尾。通过多次重复这个过程,直到所有元素按照升序排列为止。

3. 插入排序(Insertion Sort)

插入排序是一种简单且稳定的排序算法。它通过将未排序的元素逐个插入到已排序部分的正确位置。每次插入一个元素,已排序部分都是有序的。通过多次重复这个过程,直到所有元素按照升序排列为止。

4. 快速排序(Quick Sort)

快速排序是一种高效的排序算法。它通过选择一个基准元素,将数组分成两部分,一部分元素小于基准,另一部分元素大于基准。然后对这两部分递归地进行快速排序。通过多次重复这个过程,直到所有元素按照升序排列为止。

5. 归并排序(Merge Sort)

归并排序是一种稳定的排序算法。它通过将数组递归地分成两半,分别对这两半进行归并排序,然后将排序好的两部分合并起来。通过多次重复这个过程,直到所有元素按照升序排列为止。

6. 堆排序(Heap Sort)

堆排序是一种高效的排序算法。它利用堆的性质来进行排序,通过构

建一个最大堆或最小堆,并不断地取出堆顶元素并调整堆。通过多次重复

这个过程,直到所有元素按照升序排列为止。

7. 计数排序(Counting Sort)

各种排序算法的总结和比较

各种排序算法的总结和比较

各种排序算法的总结和比较

1 快速排序(QuickSort)

快速排序是一个就地排序,分而治之,大规模递归的算法。从本质上来说,它是归并排序的就地版本。快速排序可以由下面四步组成。

(1)如果不多于1个数据,直接返回。

(2)一般选择序列最左边的值作为支点数据。(3)将序列分成2部分,一部分都大于支点数据,另外一部分都小于支点数据。

(4)对两边利用递归排序数列。

快速排序比大部分排序算法都要快。尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。快速排序是递归的,对于内存非常有限的机器来说,它不是一个好的选择。

2 归并排序(MergeSort)

归并排序先分解要排序的序列,从1分成2,2分成4,依次分解,当分解到只有1个一组的时候,就可以排序这些分组,然后依次合并回原来的序列中,这样就可以排序所有数据。合并排序比堆排序稍微快一点,但是需要比堆排序多一倍的内存空间,因为它需要一个额外的数组。

3 堆排序(HeapSort)

堆排序适合于数据量非常大的场合(百万数据)。

堆排序不需要大量的递归或者多维的暂存数组。这对于数据量非常巨大的序列是合适的。比如超过数百万条记录,因为快速排序,归并排序都使用递归来设计算法,在数据量非常大的时候,可能会发生堆栈溢出错误。

堆排序会将所有的数据建成一个堆,最大的数据在堆顶,然后将堆顶数据和序列的最后一个数据交换。接下来再次重建堆,交换数据,依次下去,就可以排序所有的数据。

Shell排序通过将数据分成不同的组,先对每一组进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。平均效率是O(nlogn)。其中分组的合理性会对算法产生重要的影响。现在多用D.E.Knuth的分组方法。

各种经典排序算法

各种经典排序算法

排 序
4、排序的稳定性
在待排序的文件中,若存在 多个关键字相同的记录,经 过排序后这些具有相同关键 字的记录之间的相对次序保 持不变,该排序方法是稳定 的; 若有: {R1 ,..., Ri,...,Rj,.....} 且关键字: Ki=Kj 排序后: i<>j
{ Ri,Rj,.....} 若具有相同关键字的记录之 间的相对次序发生变化,则 则称该排序结果具有稳定性。 称这种排序方法是不稳定的。
排 序
三、交换排序
两两比较待排序记录的关键字,发现两个记录次序 相反时即进行交换,直到没有反序的记录为止。
冒泡排序
快速排序
排 序
7.3.1 冒泡排序——基本思想和过程
假设在排序过程中,记录序列L.r[1..n]的状态为:
n-i+1
无序序列L.r[1..n-i+1] 有序序列 L.r[n-i+2..n]
有序序列L.r[1..i-1]
L.r[i]
无序序列 L.r[i..n]
有序序列L.r[1..i]
无序序列 L.r[i+1..n]
排 序
方法:
1.在L.r[1..i-1]中查找L.r[i]的插入位臵,
L.r[1..j] L.r[i] < L.r[j+1..i-1];
2.将L.r[j+1..i-1]中的所有记录均后移 一个位臵;

java8 list 排序方法

java8 list 排序方法

java8 list 排序方法

Java 8中的List排序是一种排序列表的方法,允许程序员利用多种静态和实例方法来对所有可能的列表进行排序,其中包括链表、阵列和泛型捕获列表。

1、比较器排序:

比较器排序是在Java 8中极其常见的排序方法,它用来在列表中比较元素的特定属性,例如它们的大小或其他标准,来使列表以特定的顺序排列。

2、递归排序:

递归排序是一种排序列表的技术,它将列表不断分割,然后对每个分段进行排序,最终将每个段的元素合并。它在Java 8中可以使用Collections类对列表字段进行排序。

3、算法排序:

算法排序是一种利用排序算法来操作列表元素的技术,它仅适用于特定情况,例如旋转列表中的数据以提高性能。在Java 8中,开发人员可以使用两种排序算法,即归并排序和快速排序。

4、排序工厂:

在Java 8中,排序工厂是一种非常有用的排序方法,它可以根据用户

提供的排序要求自动完成列表元素的排序操作,而不用在代码中实现每一步操作。

5、定制排序:

定制排序是允许开发人员根据自己的命名条件来排列列表元素的灵活技术,Java 8中有一个实用程序类,可让用户以正确的列表顺序对元素进行排序,而无需任何额外的参数指定。

6、元素索引排序:

元素索引排序是通过给每个元素定义一个唯一的索引值来根据特定索引排列列表元素的方法,这种排序方法可以非常有效地根据列表中的不同元素进行排列。

7、Stream API排序:

Stream API排序是在Java 8中非常受欢迎的一种排序方法,它将简单的排序组合在一起并返回结果,这一功能可以在无需重写比较器的情况下完成排序,而不必担心性能问题。它可以很容易地将元素按照指定条件进行排序。

八大排序算法

八大排序算法

八大排序算法

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

我们这里说说八大排序就是内部排序。

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。

快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

基本思想:

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

要点:设立哨兵,作为临时存储和判断数组边界之用。

直接插入排序示例:

如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

算法的实现:

[cpp]view plaincopyprint?

1.void print(int a[], int n ,int i){

2. cout<

3.for(int j= 0; j<8; j++){

4. cout<

5. }

6. cout<

7.}

8.

9.

10.void InsertSort(int a[], int n)

11.{

12.for(int i= 1; i

13.if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。小于的话,

移动有序表后插入

14.int j= i-1;

程序设计竞赛常用算法

程序设计竞赛常用算法

程序设计竞赛常用算法

1.排序算法:

排序是一个基本的算法问题,常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等。这些排序算法有各自的优势和适用场景,需要根据具体问题需求选择合适的算法。

2.图论算法:

图论是程序设计竞赛中经常出现的重要领域。常见的图论算法有深度

优先(DFS)、广度优先(BFS)、Dijkstra算法、Floyd-Warshall算法、拓扑排序、最小生成树等。这些算法可以用于解决最短路径、连通性、最

大流最小割等问题。

3.动态规划:

动态规划是一种常用于解决优化问题的算法。该算法通过将问题分解

成子问题,并记录子问题的解来求解原问题的最优解。常见的动态规划算

法有背包问题、最长公共子序列(LCS)、最大子序列和等。

4.字符串处理算法:

字符串处理是程序设计竞赛中常见的问题。常见的字符串处理算法有KMP算法、哈希算法、字符串匹配等。这些算法可以用于解决模式匹配、

字符串、字符统计等问题。

5.数学算法:

数学算法在程序设计竞赛中也经常被使用。常见的数学算法有质因数

分解、素数筛、快速乘法、高精度计算等。这些算法可以用于解决数论、

计算几何、概率等问题。

6.图形算法:

图形算法主要用于处理图像和几何图形。常见的图形算法有扫描线算法、凸包算法、几何运算等。这些算法可以用于解决图像处理、三维建模等问题。

7.树和图的遍历算法:

树和图的遍历算法是程序设计竞赛中常用的算法之一、常见的树和图的遍历算法有先序遍历、中序遍历、后序遍历、深度优先(DFS)、广度优先(BFS)等。这些算法可以用于解决树和图的构建、路径等问题。

排序算法十大经典方法

排序算法十大经典方法

排序算法十大经典方法

排序算法是计算机科学中的经典问题之一,它们用于将一组元素按照一定规则排序。以下是十大经典排序算法:

1. 冒泡排序:比较相邻元素并交换,每一轮将最大的元素移动到最后。

2. 选择排序:每一轮选出未排序部分中最小的元素,并将其放在已排序部分的末尾。

3. 插入排序:将未排序部分的第一个元素插入到已排序部分的合适位置。

4. 希尔排序:改进的插入排序,将数据分组排序,最终合并排序。

5. 归并排序:将序列拆分成子序列,分别排序后合并,递归完成。

6. 快速排序:选定一个基准值,将小于基准值的元素放在左边,大于基准值的元素放在右边,递归排序。

7. 堆排序:将序列构建成一个堆,然后一次将堆顶元素取出并调整堆。

8. 计数排序:统计每个元素出现的次数,再按照元素大小输出。

9. 桶排序:将数据分到一个或多个桶中,对每个桶进行排序,最后输出。

10. 基数排序:按照元素的位数从低到高进行排序,每次排序只考虑一位。

以上是十大经典排序算法,每个算法都有其优缺点和适用场景,选择合适的算法可以提高排序效率。

风靡全球的十大算法

风靡全球的十大算法

风靡全球的十大算法

1 排序算法

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。

稳定的

•冒泡排序(bubble sort)— O(n^2)

•鸡尾酒排序(Cocktail sort,双向的冒泡排序) — O(n^2)

•插入排序(insertion sort)— O(n^2)

•桶排序(bucket sort)— O(n); 需要 O(k) 额外空间

•计数排序(counting sort) — O(n+k); 需要 O(n+k) 额外空间

•合并排序(merge sort)— O(nlog n);需要 O(n) 额外空间

•原地合并排序— O(n^2)

•二叉排序树排序(Binary tree sort)— O(nlog n)期望时间;O(n^2)最坏时间;需要 O(n) 额外空间

•鸽巢排序(Pigeonhole sort)— O(n+k); 需要 O(k) 额外空间

•基数排序(radix sort)—O(n·k); 需要 O(n) 额外空间

•Gnome 排序— O(n^2)

•图书馆排序— O(nlog n) withhigh probability,需要(1+ε)n 额外空间

不稳定的

•选择排序(selection sort)— O(n^2)

•希尔排序(shell sort)— O(nlog n) 如果使用最佳的现在版本•组合排序— O(nlog n)

十大经典排序算法(动图演示)

十大经典排序算法(动图演示)

⼗⼤经典排序算法(动图演⽰)

0、算法概述

0.1 算法分类

⼗种常见排序算法可以分为两⼤类:

⽐较类排序:通过⽐较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为⾮线性时间⽐较类排序。

⾮⽐较类排序:不通过⽐较来决定元素间的相对次序,它可以突破基于⽐较排序的时间下界,以线性时间运⾏,因此也称为线性时间⾮⽐较类排序。

0.2 算法复杂度

0.3 相关概念

稳定:如果a原本在b前⾯,⽽a=b,排序之后a仍然在b的前⾯。

不稳定:如果a原本在b的前⾯,⽽a=b,排序之后 a 可能会出现在 b 的后⾯。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机

内执⾏时所需存储空间的度量,它也是数据规模n的函数。

1、冒泡排序(Bubble Sort)

冒泡排序是⼀种简单的排序算法。它重复地⾛访过要排序的数列,⼀次⽐较两个元素,如果它们的顺序错误就把它们交换过来。⾛访数列的⼯作是重复地进⾏直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越⼩的元素会经由交换慢慢“浮”到数列的顶端。

1.1 算法描述

⽐较相邻的元素。如果第⼀个⽐第⼆个⼤,就交换它们两个;

对每⼀对相邻元素作同样的⼯作,从开始第⼀对到结尾的最后⼀对,这样在最后的元素应该会是最⼤的数;

针对所有的元素重复以上的步骤,除了最后⼀个;

重复步骤1~3,直到排序完成。

1.2 动图演⽰

1.3 代码实现

function bubbleSort(arr) {

var len = arr.length;

十大经典排序算法

十大经典排序算法

⼗⼤经典排序算法

前⾔说明

⼗⼤排序算法可以说是每个程序员都必须得掌握的了,花了⼀天的时间把代码实现且整理了⼀下,为了⽅便⼤家学习,我把它整理成⼀篇⽂章,每种算法会有简单的算法思想描述,为了⽅便⼤家理解,我还找来了动图演⽰;这还不够,我还附上了对应的优质⽂章,看完不懂你来砍我,如果不想砍我就给我来个好看。

术语解释

有些⼈可能不知道什么是稳定排序、原地排序、时间复杂度、空间复杂度,我这⾥先简单解释⼀下:

1、稳定排序:如果 a 原本在 b 的前⾯,且 a == b,排序之后 a 仍然在 b 的前⾯,则为稳定排序。

2、⾮稳定排序:如果 a 原本在 b 的前⾯,且 a == b,排序之后 a 可能不在 b 的前⾯,则为⾮稳定排序。

3、原地排序:原地排序就是指在排序过程中不申请多余的存储空间,只利⽤原来存储待排数据的存储空间进⾏⽐较和交换的数据排序。

4、⾮原地排序:需要利⽤额外的数组来辅助排序。

5、时间复杂度:⼀个算法执⾏所消耗的时间。

6、空间复杂度:运⾏完⼀个算法所需的内存⼤⼩。

⼗⼤排序

为了⽅便⼤家查找,我这⾥弄⼀个伪⽬录。

选择排序

插⼊排序

冒泡排序

⾮优化版本

优化版本

希尔排序

归并排序

递归式归并排序

⾮递归式归并排序

快速排序

堆排序

基数排序

⾮优化版本

优化版本

桶排序

基数排序

1、选择排序

过程简单描述:

⾸先,找到数组中最⼩的那个元素,其次,将它和数组的第⼀个元素交换位置(如果第⼀个元素就是最⼩元素那么它就和⾃⼰交换)。其次,在剩下的元素中找到最⼩的元素,将它与数组的第⼆个元素交换位置。如此往复,直到将整个数组排序。这种⽅法我们称之为选择排序。

用Java实现常见的8种内部排序算法

用Java实现常见的8种内部排序算法

⽤Java实现常见的8种内部排序算法

⼀、插⼊类排序

插⼊类排序就是在⼀个有序的序列中,插⼊⼀个新的关键字。从⽽达到新的有序序列。插⼊排序⼀般有直接插⼊排序、折半插⼊排序和希尔排序。

1. 插⼊排序

1.1 直接插⼊排序

/**

* 直接⽐较,将⼤元素向后移来移动数组

*/

public static void InsertSort(int[] A) {

for(int i = 1; i < A.length; i++) {

int temp = A[i]; //temp ⽤于存储元素,防⽌后⾯移动数组被前⼀个元素覆盖

int j;

for(j = i; j > 0 && temp < A[j-1]; j--) { //如果 temp ⽐前⼀个元素⼩,则移动数组

A[j] = A[j-1];

}

A[j] = temp; //如果 temp ⽐前⼀个元素⼤,遍历下⼀个元素

}

}

/**

* 这⾥是通过类似于冒泡交换的⽅式来找到插⼊元素的最佳位置。⽽传统的是直接⽐较,移动数组元素并最后找到合适的位置

*/

public static void InsertSort2(int[] A) { //A[] 是给定的待排数组

for(int i = 0; i < A.length - 1; i++) { //遍历数组

for(int j = i + 1; j > 0; j--) { //在有序的序列中插⼊新的关键字

if(A[j] < A[j-1]) { //这⾥直接使⽤交换来移动元素

int temp = A[j];

十大排序算法

十大排序算法

⼗⼤排序算法

算法之排序

排序算法基本上是我们⽆论是在项⽬中还是在⾯试中都会遇到的问题,加上最近在看《算法》这本书,所以就准备好好的将排序算法整理⼀下。

所有排序算法都是基于 Java 实现,为了简单,只使⽤了int类型,从⼩到⼤排序

基本排序

⾼效的排序

各⼤排序的时间测试

如何选择排序

排序之基本排序算法

准备阶段:有⼀个交换位置的函数exc

/**

* 交换a数组中i和j的位置

* @param a 需要交换的数组

* @param i 位置

* @param j 位置

*/

public static void exc(int a[],int i,int j){

// 当他们相等的时候就没必要进⾏交换

if(a[i] != a[j]){

a[i] ^= a[j];

a[j] ^= a[i];

a[i] ^= a[j];

}

}

基本排序算法主要是分为插⼊排序,选择排序,冒泡排序和梳排序。

选择排序

原理:选择排序的原理很简单,就是从需要排序的数据中选择最⼩的(从⼩到⼤排序),然后放在第⼀个,选择第⼆⼩的放在第⼆个……

代码:

/**

* 选择排序

* @param a 进⾏排序的数组

*/

public static int[] selectionSort(int a[]){

int min;

for(int i=0;i<a.length;i++){

min = i;

// 这个for循环是为了找出最⼩的值

for (int j = i+1; j < a.length; j++) {

if(a[min]>a[j]){

min = j;

8种排序算法

8种排序算法

一、插入排序(Insertion Sort)1. 基本思想:每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。2. 排序过程: 【示例】:[初始关键字] [49] 38 65 97 76 13 27 49J=2(38) [38 49] 65 97 76 13 27 49J=3(65) [38 49 65] 97 76 13 27 49J=4(97) [38 49 65 97] 76 13 27 49J=5(76) [38 49 65 76 97] 13 27 49J=6(13) [13 38 49 65 76 97] 27 49J=7(27) [13 27 38 49 65 76 97] 49J=8(49) [13 27 38 49 49 65 76 97] 二、选择排序1. 基本思想: 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。2. 排序过程:【示例】:初始关键字 [49 38 65 97 76 13 27 49]第一趟排序后 13 [38 65 97 76 49 27 49]第二趟排序后 13 27 [65 97 76 49 38 49]第三趟排序后 13 27 38 [97 76 49 65 49]第四趟排序后 13 27 38 49 [49 97 65 76]第五趟排序后 13 27 38 49 49 [97 97 76]第六趟排序后 13 27 38 49 49 76 [76 97]第七趟排序后 13 27 38 49 49 76 76 [ 97]最后排序结果 13 27 38 49 49 76 76 97三、冒泡排序(BubbleSort)1. 基本思想: 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。2. 排序过程: 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。【示例】:49 13 13 13 13 13 13 13 38 49 27 27 27 27 27 2765 38 49 38 38 38 38 3897 65 38 49 49 49 49 4976 97 65 49 49 49 49 4913 76 97 65 65 65 65 6527 27 76 97 76 76 76 7649 49 49 76 97 97 97 97 四、快速排序(Quick Sort)1. 基本思想:在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。2. 排序过程: 【示例】:初始关键字 [49 38 65 97 76 13 27 49]第一次交换后 [27 38 65 97 76 13 49 49] 第二次交换后 [27 38 49 97 76 13 65 49] J向左扫描,位置不变,第三

各种排序方法汇总

各种排序方法汇总

一.选择排序

1. 选择排序法基本思想:

每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

2. 排序过程:

【示例】:

初始关键字[49 38 65 97 76 13 27 49]

第一趟排序后13 [38 65 97 76 49 27 49]

第二趟排序后13 27 [65 97 76 49 38 49]

第三趟排序后13 27 38 [97 76 49 65 49]

第四趟排序后13 27 38 49 [49 97 65 76]

第五趟排序后13 27 38 49 49 [97 97 76]

第六趟排序后13 27 38 49 49 76 [76 97]

第七趟排序后13 27 38 49 49 76 76 [ 97]

最后排序结果13 27 38 49 49 76 76 97

3.

void selectionSort(Type* arr,long len)

{

long i=0,j=0;/*iterator value*/

long maxPos;

assertF(arr!=NULL,"In InsertSort sort,arr is NULL\n");

for(i=len-1;i>=1;i--)

{

maxPos=i;

for(j=0;j

if(arr[maxPos]< P>

if(maxPos!=i)swapArrData(arr,maxPos,i);

}

}

选择排序法的第一层循环从起始元素开始选到倒数第二个元素,主要是在每次进入的第二层循环之前,将外层循环的下标赋值给临时变量,接下来的第二层循环中,如果发现有比这个最小位置处的元素更小的元素,则将那个更小的元素的下标赋给临时变量,最后,在二层循环退出后,如果临时变量改变,则说明,有比当前外层

经典十大排序算法

经典十大排序算法

经典⼗⼤排序算法

前⾔

排序种类繁多,⼤致可以分为两⼤类:

⽐较类排序:属于⾮线性时间排序,时间复杂度不能突破下界O(nlogn);

⾮⽐较类排序:能达到线性时间O(n),不是通过⽐较来排序,有基数排序、计数排序、桶排序。

了解⼀个概念:排序的稳定性

稳定是指相同⼤⼩的元素多次排序能保证其先后顺序保持不变。假设有⼀些学⽣的信息,我们先根据他们的姓名进⾏排序,然后我们还想根据班级再进⾏排序,如果这时使⽤的时不稳定的排序算法,那么第⼀次的排序结果可能会被打乱,这样的场景需要使⽤稳定的算法。

堆排序、快速排序、希尔排序、选择排序是不稳定的排序算法,⽽冒泡排序、插⼊排序、归并排序、基数排序是稳定的排序算法。

1、冒泡排序

⼤多数⼈学编程接触的第⼀种排序,名称很形象。每次遍历排出⼀个最⼤的元素,将⼀个最⼤的⽓泡冒出⽔⾯。

时间复杂度:平均:O(n2);最好:O(n);最坏:O(n2)

空间复杂度:O(1)

public static void bubbleSort(int[] arr) {

/**

* 总共⾛len-1趟即可,每趟排出⼀个最⼤值放在最后

*/

for (int i = 0; i < arr.length - 1; i++) {

for (int j = 0; j < arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {

int tp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = tp;

}

}

}

}

2、选择排序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

概述

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

我们这里说说八大排序就是内部排序。

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。

快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

1.插入排序—直接插入排序(Straight Insertion Sort)

基本思想:

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

要点:设立哨兵,作为临时存储和判断数组边界之用。

直接插入排序示例:

如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

算法的实现:

1.void print(int a[], int n ,int i){

2. cout<

3.for(int j= 0; j<8; j++){

4. cout<

5. }

6. cout<

7.}

8.

9.

10.void InsertSort(int a[], int n)

11.{

12.for(int i= 1; i

13.if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。

小于的话,移动有序表后插入

14.int j= i-1;

15.int x = a[i]; //复制为哨兵,即存储待排序元素

16. a[i] = a[i-1]; //先后移一个元素

17.while(x < a[j]){ //查找在有序表的插入位置

18. a[j+1] = a[j];

19. j--; //元素后移

20. }

21. a[j+1] = x; //插入到正确位置

22. }

23. print(a,n,i); //打印每趟排序的结果

24. }

25.

26.}

27.

28.int main(){

29.int a[8] = {3,1,5,7,2,4,9,6};

30. InsertSort(a,8);

31. print(a,8,8);

32.}

效率:

时间复杂度:O(n^2).

其他的插入排序有二分插入排序,2-路插入排序。

2. 插入排序—希尔排序(Shell`s Sort)

希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序

基本思想:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”

时,再对全体记录进行依次直接插入排序。

操作方法:

1. 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;

2. 按增量序列个数k,对序列进行k 趟排序;

3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对

各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

希尔排序的示例:

算法实现:

我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数

即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。

1.void print(int a[], int n ,int i){

2. cout<

3.for(int j= 0; j<8; j++){

4. cout<

5. }

6. cout<

7.}

8./**

9. * 直接插入排序的一般形式

10. *

11. * @param int dk 缩小增量,如果是直接插入排序,dk=1

12. *

13. */

14.

15.void ShellInsertSort(int a[], int n, int dk)

16.{

17.for(int i= dk; i

18.if(a[i] < a[i-dk]){ //若第i个元素大于i-1元素,直接插入。小于的

话,移动有序表后插入

19.int j = i-dk;

20.int x = a[i]; //复制为哨兵,即存储待排序元素

21. a[i] = a[i-dk]; //首先后移一个元素

22.while(x < a[j]){ //查找在有序表的插入位置

23. a[j+dk] = a[j];

24. j -= dk; //元素后移

25. }

26. a[j+dk] = x; //插入到正确位置

27. }

28. print(a, n,i );

29. }

30.

31.}

32.

33./**

34. * 先按增量d(n/2,n为要排序数的个数进行希尔排序

35. *

36. */

37.void shellSort(int a[], int n){

38.