数据结构——常见的十种排序算法

一、常见的十种排序算法:

冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序、堆排序、计数排序、桶排序、基数排序

1.【知识框架】

补充:内部排序:整个排序过程完全在内存中进行。

外部排序:由于待排序记录数据量太大,内存无法容纳全部数据,需要借助外部存储。


二、排序方法

?插入排序

1.算法思想

从待排序的第二个元素开始,向下扫描列表,比较这个目标值target与arr[i-1]、arr[i-2]的大小,依次类推。如果target的值小于或等于每一个元素值,那么每个元素都会向右滑动一个位置,一旦确定了正确位置j,目标值target(即原始的arr[i])就会被复制到这个位置。(例如:整理桥牌时,我们会将每一张牌插入到一个已经有序的序列的适当位置。为了给要插入的元素腾出空间,需要我们将已经有序的序列元素都向右移动一位)

2.算法实现

3.插入排序伪代码

 1 void InsertSort (ElemType A[], int n)
 2 {
 3    int i,j;
 4    for(i=2;i<=n;i++)
 5         if(A[i].key<A[i-1].key)
 6     {
 7         A[0]=A[i];
 8         for(j=i-1;A[0].key<A[j].key;--j)
 9                 A[j+i]=A[j];
10         A[j+i]=A[0];
11     }
12 }

4.稳定性

由于每次插入元素时总是从后往前先比较在移动,所以不会出现相同元素相对位置,发生变化的情况即直接插入排序是一个稳定的排序方法

5.时间复杂度:O(n2

?希尔排序(缩小增量排序)

1.算法提出:

为解决插入排序每次只能将数据移动一位,在数组较大且基本无序的情况下性能出现的恶化所以引入其算法。
2.算法思想: 

先取一个小于n的步长d1把表中全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中,在各组中进行直接插入排序:然后取第二个步长d2<d1,重复上       述过程,直到所取到的d1=1,即所有记录已放在同一组中,再进行直接插入排序,由于此时已经具有较好的局部有序性,故可以很快得到最终结果。到目前为         止,尚未求得一个最好的增量序列,希尔提出的方法是d1=n/2,di+1=?di/2? , 并且最后一个增量等于 1。

3.算法实现:

补充:操作原理时间复杂度与选取的增量序列有关且所取增量序列的函数介于O(N*logN)和O(n2)之间增量序列有很多种取法,但是使增量序列中的值没有除1之外的公因子,并且增量序列中最后一个值必须为1。

4.插入排序伪代码

 1 void ShellSort (ElemType A[],int n){
 2 //对顺序表作希尔插入排序,基本算法和直接插入排序相比,做了以下修改:
 3 //1.前后记录位置的增量是dk,不是1
 4 //2.r[0]只是暂时存储单元,不是哨兵,当j<=0时,插入位置已到
 5       for(dk=n/2;dk>=1,dk=dk/2)                                   //步长变化
 6            for(i=dk+1;i<=n;++i)
 7                  if(A[i].key<A[i-dk].key){                        //需将A[i]插入有序增量子表
 8                      A[0]=A[i];
 9                      for(j=i-dk;j>0&&A[0].key<A[j].key;j-=dk)
10                           A[j+dk]=A[j];                           //记录后移,查找插入位置
11                      A[j+dk]=A[0];                                //插入
12                }//if
13   }

5.稳定性

当相同关键字的记录被划分到不同的子表时,可能会改变它们之间的相对次序,因此,希尔排序是一种不稳定的排序方法。例如,表L=[3,2,2].经过一趟排序后,

L=[2,2,3],最终排序序列也是L=[2,2,3],显然2与2的相对次序已经发生了变化。

6.时间复杂度:O(N*logN)

?选择排序

1.算法思想

Step1:将待排序数组分为有序和无序两组(初始情况下有序组为空)

Step2:从左向右扫描无序组,找出最小的元素,将其放置在无序组的第一个位置。至此有序组++,无序组--;

Step3:重复Step2,直至无序组只剩下一个元素。

2.算法实现

3.插入排序伪代码

 1 void ShellSort (ElemType A[],int n){
 2 //对表A作简单的选择排序,A[]从0开始放元素
 3       for(i=0;i<=n-1;i++){                                //一共进行n-1趟
 4           min=i;                                          //记录最小元素位置
 5               for(j=i+1;j<n;j++)                          //在A[i...n-1]中选择最小的元素
 6                      if(A[j]<A[min])
 7                            min=j;                         //更新最小元素位置
 8 if(min!=i)  swap(A[i],A[min]);                            //在第n个元素交换
 9
10                }
11 }

4.时间复杂度: O(n2)

5.稳定性:

选择排序的时间复杂度为O(n2),由于每次选择仅考虑某一位置上的数据情况,可能会破坏之前数据的相对位置,因此它是一种不稳定的排序方法。 例如:序列[9,9,1]第一次就将第一个[9]与[1]交换,导致第一个9挪动到第二个9后面。

补充:简单选择排序的比较次数与序列的初始排序无关。假设待排序的序列有 n个元素,选择排序的赋值操作介于0和3(n - 1) 次之间; 则比较次数 永远都是n (n- 1) / 2; 而移动次数(即:交换操作)与序列的初始排序有关,介于 0 和 (n - 1) 次之间。当序列正序时,移动次数最少,为 0。当序列反序时,移动次数最多,为n - 1 次;逆序交换n/2次。选择排序的移动次数比冒泡排序少多了,由于交换所需CPU时间比 比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

后续未完...

  

 

原文地址:https://www.cnblogs.com/blancheiii/p/10029530.html

时间: 2024-10-12 20:48:42

数据结构——常见的十种排序算法的相关文章

数据结构常见的八大排序算法(详细整理)

https://www.jianshu.com/p/7d037c332a9d?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-friends 八大排序,三大查找是<数据结构>当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法.常见的八大排序算法,他们之间关系如下: 排序算法.png 他们的性能比较: 性能比较.png 下面,利用Python分别将他

数据结构-十大经典排序算法

常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 关于时间复杂度 平方阶 (O(n2)) 排序 各类简单排序:直接插入.直接选择和冒泡排序. 线性对数阶 (O(nlog2n)) 排序 快速排序.堆排序和归并排序: O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数. 希尔排序 线性阶 (O(n)) 排序 基数排序,此外还有桶.箱排序. 关于稳定性 稳定的排序算法:冒泡排序.插入排序.归并排序和基数排序. 不是稳定的排序算

常见的比较排序算法

比较排序是比较常见的排序算法,它分为以下几个类: 交换排序:冒泡排序(BubbleSort)和快速排序(QuickSort). 插入排序:直接插入排序和希尔排序(ShellSort). 选择排序:选择排序(SelectSort)和堆排序(HeapSort). (一)交换排序: void BubbleSort(int* arry, int size) { for (int i = 0; i < size - 1; i++) { for (int j = 0; j < size - i - 1; 

数据结构6种内部排序算法的比较

1.需求分析 (1)输入数据的形式为:伪随机数产生程序产生,且每次输入数不少于100个,至少要用5组不同的输入数据 (2)输出的形式为:输出关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)的数据 (3)程序能达到的功能:对起泡排序,直接插入排序,简单选择排序,快速排序,希尔排序,堆排序这6种常用的内部排序算法进行比较,比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动) (4)测试数据:正确输入为由伪随机数产生程序产生100个随机数,然后输出比较结果,错

【数据结构】非比较排序算法(实现计数排序和基数排序)

● 计数排序 1.算法思想: 计数排序是直接定址法的变形.通过开辟一定大小的空间,统计相同数据出现的次数,然后回写到原序列中. 2.步骤: 1)找到序列中的最大和最小数据,确定开辟的空间大小. 2)开辟空间,利用开辟的空间存放各数据的个数. 3)将排好序的序列回写到原序列中. 具体实现如下: void CountSort(int *arr, int size) {  assert(arr);  int min = arr[0];  int max = arr[0];  int num = 0;

常见的七大排序算法Java实现

/** * @author Javen * @Email [email protected] * 2015年12月9日 */ public class Sorting { static int[] array = new int[]{11, 31, 12, 5, 34, 30, 26, 38, 36, 18}; public static void main(String[] args) { //插入排序 System.out.println(array2String(sortInsert(ar

十种排序算法总结(代码及说明)

1.冒泡排序 基本思想是:两两比较相邻记录的关键字,如果反序则交换 冒泡排序时间复杂度最好的情况为O(n),最坏的情况是O(n^2) 改进思路1:设置标志位,明显如果有一趟没有发生交换(flag = false),说明排序已经完成 改进思路2:记录一轮下来标记的最后位置,下次从头部遍历到这个位置就Ok. 原冒泡排序代码如下: void swap(int left, int right) { left = left ^ right; right = right ^ left; left = lef

数据结构(九)排序算法

排序算法总结: 快速排序算法: 是基于分治的算法,关键在于划分操作: 性能分析:  堆排序: 归并排序: 拓扑排序: 原文地址:https://www.cnblogs.com/ST-2017/p/10498894.html

数据结构复习之内部排序算法总结

1.三种选择排序(简单选择排序,树形选择排序,堆排序) #include<iostream> #include<cstring> #include<string> #include<queue> #include<map> #include<cstdlib> #include<cstdio> const int INF=0X3f3f3f3f; using namespace std; typedef struct { in