数据结构8-排序

37 阅读8分钟

排序

1.基本概念和排序方法概述

  • 排序的基本概念
  • 内部排序方法的分类
  • 待排序记录的存储方法
  • 排序算法效率的评价指标

2.插入排序

  • 直接插入排序
  • 折半插入排序
  • 希尔排序

3.交换排序

  • 冒泡排序
  • 快速排序

4.选择排序

  • 简单选择排序
  • 树形选择排序
  • 堆排序

5.归并排序

6.基数排序

  • 多关键字的排序
  • 链式基数的排序

1.1排序的基本概念

排序:是按照关键字的非递减或非递增顺序对一组记录重新进行排序的操作

排序的稳定性:对多个相同关键字而言,在排序前和排序后,相同的关键字的相对位置不发生改变,则说排序是稳定的

内部排序和外部排序:内部排序指的是待排序记录全部存放在计算机内存中进行排序的过程,外部排序指的是待排序记录的数量很大,以至于内存一次性不能容纳全部记录,在排序过程中尚需对外存进行访问的排序过程

1.2内部排序方法的分类

内部排序的过程:

逐渐扩大记录的有序序列长度的过程,在排序过程中,可以将排序记录区分为两个区域:有序序列区和无序序列区

排序:

使有序区中记录的数目增加的操作

🔴:排序过程中,总长度不会发生改变,改变的仅仅是有序序列区和无序序列区的长度

插入类:直接插入排序,折半插入排序,希尔排序

(将无序子序列中一个或多个记录插入有序序列)

交换类:冒泡排序,快速排序

(通过交换无序序列中的记录,从而得到其中关键字最小或最大的记录,并将它加入到有序子序列中)

选择类:简单选择排序,树形选择排序,堆排序

(从记录的无序子序列中选择关键字最小或最大的记录,并加入到有序子序列中)

归并类:归并排序

(通过归并两个及以上的记录有序子序列,逐渐扩大有序序列长度)

分配类:基数排序(多关键字的排序,链式基数的排序)

1.3待排序记录的存储方式

1.顺序表排序:记录之间的次序关系由其存储位置决定,排序需要移动记录

2.链表排序:记录之间的次序关系由指针指示,排序不需要移动记录,仅修改指针

3.地址排序:待排序记录本身存储在一组地址连续的存储单元内,同时设一个指示各个记录存储位置的地址向量,排序不需要移动记录,而移动地址向量

1.4排序算法效率的评价指标(顺序表)

1.执行时间:时间消耗在关键字之间的比较和记录的移动上

2.辅助空间:空间的复杂度是由排序算法所需的辅助空间决定的

辅助空间:除了存放待排序记录占用的空间之外,执行算法所需要的其他存储空间

O(0)代表所需的辅助空间与待排序的数据量无关(理想的空间复杂度)


2.1插入排序

🔴:添加一个监视哨,将要排序的记录放在监视哨(即数组下标为0的位置上)

【防止在比较时,数组下标越界,也减少时间复杂度】

2.1.1直接插入排序

步骤:

1.先将要排序的记录放在监视哨中

2.向后移动其他记录,直到找到待排序的记录插入的位置

🔵:从后往前进行比较

2.1.2折半插入排序

折半插入排序运用了二分法

步骤:

1.先将待排序的记录存放在数组中,将待插入的记录存放在监视哨中

2.置查找区间初值(即分开两块区间)

3.运用二分法查找,直到找到相应位置

4.将监视哨待排序的记录拿出来放在指定位置

2.1.3希尔排序

希尔排序又称缩小增量排序

  • 它的实质是采用分组插入的方法,不断的分组,不断的插入,组内的单元每一次分组都减少

(即:第一次分组,组内单元有5个,第二次分组,组内单元有3个,第三次分组,组内单元有1个)

🔴最后一次分组,组内单元必须只能有1个

3.2交换排序

3.1.1冒泡排序(递减序列变成递增序列)

冒泡排序的序列结果是递增的序列

算法:

每一趟排序结束后,都得到一个最大值排到最后(除了已经排序过的记录)

用flag来标记某趟排序是否发生交换(可能出现已经排序好的序列,这时候就不需要再次排序了)

从第一个记录开始比较并排序

1.循环:当flag==1且下标不越界

  • 初始化flag=0,和后一个记录比较

  • 如果大于后一个记录,交换,并让flag=1

  • 如果小于后一个记录,不交换,flag=0

    (注意:每趟排序需要比较的次数是逐渐减1次)

3.1.2快速排序

快速排序的前提是在冒泡排序的基础上进行的,它一次性可以消除多个逆序排列

步骤:

1.在排序表中选定一个枢轴关键字,将枢轴关键字暂时存放到数组下标为0的位置上,另设两个指针low,high分别指下界和上界:low=1;high=表长

2.从表的最右侧依次向左搜索,若找到第一个关键字小于枢轴关键字的记录,high指针停留在此

3.从表的最左侧依次向右搜索,若找到第一个关键字大于枢轴关键字的记录,low指针停留在此

4.交换low,high指向的内容

5.重复步骤2.3,直到low=high(即中间的位置内容就是枢轴关键字,左边的数都小于它,右边的数都大于它)

6.在分别对左子表和右子表进行快速排序

注意:枢轴关键字一般取最左边,或者最右边,当取最左边时,需要先从右边开始查找,再从左边开始查找,反之

4.1选择排序

4.1.1简单选择排序

简单选择排序也称直接选择排序

步骤:

1.将待排序的记录存放在数组中,第一趟从下标为1开始,通过向后面比较,选出最小的关键字,然后交换

2.第二趟从下标为2开始,通过向后面比较,选出最小的关键字,然后交换

3.不断循环,直到遇到最后一个下标的记录,排序完成

4.1.2树形选择排序

树形选择排序也称锦标赛排序,可用堆排序来弥补其中的缺点

4.1.3堆排序

堆排序也是一种树形选择排序

堆:大根堆,小根堆

大根堆:每个节点的值都大于或者等于他的左右孩子的节点的值

小根堆:每个节点的值都小于或者等于他的左右孩子的节点的值

建初堆

需要对n/2以上的根检查(所有序号大于n/2的节点都是叶子,叶子已经是堆)并调整数据

5.1归并排序

归并排序就是将两个及以上的有序表合并成一个新的有序表的过程

一般使用2-路归并排序(即每次都合并两个有序表)

步骤:

设两个有序表存放在同一数组中相邻的位置

1.每次从两个表中(从左至右)各取出一个记录进行关键字比较,将较小的放入新的有序表中,

2.重复此步骤,直到一个表为空,将剩下一个非空表中剩余部分直接复制到新的有序表中

6.1基数排序

基数排序是借助于多关键字排序的思想对单关键字进行排序的方法

基数排序只能排序数字

6.1.1多关键字排序

当想要排序数字时

1.先按照个位数大小依次排序,然后十位,百位依次排序

6.1.2链式基数的排序

每一轮将多个数据按照由低位到高位的顺序,依次放在多个链表中

输出时,将链表的数据按照从上到下,从左到右的顺序依次拿出,并存储在一个新的链表中