数据结构---排序

目录

第一类:插入排序

第二类:交换排序:(排序趟数与原始状态有关)

第三类:选择排序

第四类:归并排序与基数排序

第五类:外部排序


最好情况

平均情况

最坏情况

空间复杂

稳定性

内外排序

数据对象

常考点

直接插入排序

O(n)

O(n^{2})

O(n^{2})

O(1)

稳定

内排序

数组,链表

  • 可能出现: 在最后一趟开始前, 所有元素都不在最终位置
  • 待排序序列基本有序的情况下,该方法效率最高
  • 最坏情况比较次数
  •  
  • 最好情况比较次数:n-1

希尔排序

O(nlog2n)

O(nlogn)

O(nlogn)

O(1)

不稳定

内排序

数组

  • 计算希尔排序的增量大小

冒泡排序

O(n)

O(n^{2})

O(n^{2})

O(1)

稳定

内排序

数组

快速排序

O(nlogn)

O(nlogn)

O(n^{2})

O(logn)

 

 

不稳定

内排序

数组

  • 蕴含了分而治之的思想
  • 平均性能而言,目前最好的内部排序方法
  • 当数据随机或者数据量很大的时候,适合快速排序; 当排序的数据已基本有序,不适合快速排序
  • 每次的枢纽值把表分为等长的部分 ,速度最快
  • 快速排序每趟都把基准元素放在最终位置(常用来计算是不是某一趟排序结果的题目,如第一趟至少有1个元素在最终位置,第二趟至少2个

简单选择排序

O(n^{2})

 

O(n^{2})

O(n^{2})

O(1)

不稳

内排序

数 组,

链表

  • 不怎么考
  • 数数量级与序列初始状态无关

堆排序

O(nlogn)

O(nlogn)

O(nlogn)

O(1)

不稳

内排序

数组

 归并排序

O(nlogn)

O(nlogn)

O(nlogn)

O(n)

稳定

外排序

数组,链表

  • 分阶段可以理解为就是拆分序列的过程,度为logn
  • 空间复杂度为O(n)
  • 数数量级与序列初始状态无关

基数排序

O(d(n+r))

O(d(n+r))

O(d(n+r))

O(r)

稳定

外排序

数组,链表

  • 通常基数排序第一趟按照个位数字大小,第二趟按照十位数字大小...
  • MSD是最高位优先,LSD是最低位优先
  • 基数排序不能对float和double类型的实数排序

第一类:插入排序

1.直接插入排序【  】

2.希尔排序【  】

3.折半插入排序

原理

某节点前是排好序的,节点后是未排序的

未排序数据从后向前一一比较大小并交换数据边比较边移动元素

先 整个待排序的记录序列按增量分割成若干序列,每个序列分别直接插入排序然后不断减小增量的大小,直到序列有序

先折半查找出元素的待插入位置

然后统一地移动待插入位置后的所有元素

平均复杂

0(n^{2})

O(nlogn)

0(n^{2})

稳定

稳定

不稳定

稳定

常考点

  • 可能出现: 在最后一趟开始前, 所有元素都不在最终位置
  • 待排序序列基本有序的情况下,该方法效率最高
  • 最坏情况  n × (n–1)/2
  • 最好情况:n-1

  • 计算希尔排序的增量大小
  • 折半插入排序的总趟数 = 直接插入排序的 = n-1
  • 折半插入排序元素的移动次数 = 元素的移动次数
  • 折半插入排序使用辅助空间的数量
  • 两者元素之间的个数不同

第二类:交换排序:(排序趟数与原始状态有关)

1.冒泡排序【  】

2.快速排序【  】

原理

  • 相邻的元素,如果第一个 第二个大,就交换他们两个
  • 对每一对相邻元素作同样的工 作,从开始第一对到结尾的最后一对
  • 上一步做完后,最后的元素会是最大的数
  • 针对所有的元素重复以上的步骤,除了最后一个
  • 直到没有任何一对数字需要比较
  • 通过一趟排序将要排序的数据分割成独立的两部分
  • 其中一部分的所有数据都比另外一部分的所有数据都要小
  • 然后再按此方法对这两部分数据分别进行快速排序
  • 整个排序过程可以递归进行,以此达到整个数据变成有序序列

平均复杂

0(n^{2})

0(nlogn)

稳定性

稳定

不稳定

常考点

代码:

#include <stdio.h>

void bubble_sort(int arr[], int len)

{

int i, j, temp;

for (i = 0; i < len - 1; i++)

for (j = 0; j < len - 1 - i; j++)

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

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

arr[j + 1] =temp;}

}

int main()

{

int arr[] = {22343,328255895037564,35970};

int len = (int)sizeof(arr)

/ sizeof(*arr); bubble_sort(arr, len); int i;

for (i = 0; i < len; i++) printf("%d ", arr[i]);

return 0;

}

  • 蕴含了分而治之的思想
  • 平均性能而言,目前最好的内部排序方法
  • 当数据随机或者数据量很大的时候,适合快速排序; 当排序的数据已基本有序,不适合快速排序
  • 每次的枢纽值把表分为等长的部分 ,速度最快,快速排序每趟都把基准元素放在最终位置(常用来计算是不是某一趟排序结果的题目,如第一趟至少有1个元素在最终位置,第二趟至少2个
  • 代码:

第三类:选择排序

1.简 单选择排序【 】

2.堆排序【  】

原理

  • 每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到 所有元素排完为止
  • 堆是具有特殊性质的完全二叉 
  • 大顶堆:arr[i] >= arr[2i+1] &&arr[i] >= arr[2i+2]  【根最大】
  • 小顶堆:arr[i] <= arr[2i+1] &&arr[i] <= arr[2i+2]  【根最小】
  • 堆的基本思想:a.无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆   b.堆顶元素与末尾元素交换, 最大元素"沉"到数组末端    c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素 d.反复执行调整+交换步骤,直到整个序列有序

平均复杂度

0(n^{2})

0(nlogn)

稳定性

不稳定

不稳定

常考点

  • 不怎么考
  • 数数量级与序列初始状态无关

例图

第四类:归并排序与基数排序

1. 并排序【 】

2.基数排序【  】

原理

  • 利用 并的思想实现的排序方法
  • 该算法采用经典的分治策略
  • 分治法问题分(divide)成一些小的问题然后 求解治的阶段则 分的阶段得到的各答案"修补"在一起。
  • 整数按位数切割成不同的数字,然后按每个位数分别

平均复杂

0(nlogn)

O(n*k)

稳定

稳定

稳定,外部排序

常考点

  • 分阶段可以理解为就是 拆分 序列的过程, 度为logn
  • 空间复杂度为O(n)
  • 数数量级与序列初始状态无关
  • N个元素  k  并排序k^{M}= N
  • 通常基数排序第一趟按照个位数字大小,第二趟按照十位数字大小...
  • MSD是最高位优先,LSD是最低位优先
  • 基数排序不能对float和double类型的实数 排序

例图

第五类:外部排序

概念

  • 当待排序的文件比内存的可使用容量还大,文件无法一次性放到内存中进行排序
  • 需要借助外部存储器(例如硬盘、U盘、光盘),这就需要用到外部排序算法来解决

外部排序的阶段

举例

有一个含有 10000 个记录的文件,但是内存的可使用容量仅为1000 个记录,需要使用外部排序算法,具体步骤如下:

  1. 整个文件其等分为 10 个临时文件(每个文件中含有1000 个记录)
  2. 然后 这 10 个文件依次入内存,采取适当的内存排序算法对其中的记录 排序,得到的有序文件(初始归并段)移至外存
  3. 对得到的 10 个初始归并段 如下图的两两归并,直至得到一个完整的有序文件
  4. 如上图所示有 10 个初始归并段到一个有序文件,共进行了 4次归并,每次都由 m个 归并段得到 m/2 个归并段,这种归并方式被称为 2-路平衡归并

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值