数据结构--排序

Posted 嵌入式软件开发学习圈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--排序相关的知识,希望对你有一定的参考价值。

关注“嵌入式软件开发学习圈”免费获取更多学习教程


排序的概念与分类


1.排序的定义

对于计算机中存储的数据来说,排序就是将一组“无序”的记录,通过一定的方式,按照某种关键字顺序排列调整为“有序”的记录,从而提高数据查找的效率。

2.关键字

排序中的关键字,可以是记录序列的关键字,也可以是记录序列的次关键字,或者是关键字的组合序列。

3.稳定性

若在原始记录序列中,ai和aj的关键字相同,ai出现在aj之前,经过某种方法排序后,ai的位置仍在aj之前,则称这种排序方法是稳定的;反之,若经过该方法排序后,ai的位置在aj之后,即相同关键字记录的领先关系发生变化,则称这种排序方法是不稳定的。

  数据结构--排序

 

4.排序的分类

根据数据存储位置的不同,排序可分为内部排序外部排序

若所有需要排序的数据都存放在内存中,在内存中调整数据的存储顺序,这样的排序称为内部排序

若待排序记录数据量较大,排序时只有部分数据被调入内存,排序过程中存在多次内、外存之间的交换,这样的排序称为外部排序


交换排序


交换排序(swap sorting)的核心思想:是根据序列中两条记录键值的比较结果,判断是否需要交换记录在序列中的位置。其特点是将键值较大(或较小)的记录向序列的前端移动,将键值较小(或较大)的记录向序列的后端移动


冒泡排序


1、简单的冒泡排序

       冒泡排序的基本原则是:比较两两相邻的记录的关键字,使不满足序列要求的记录交换位置,直到n-1轮循环操作结束。

       (1)从头部开始,比较相邻的两个元素arr[i]和arr[i+1],如果第二个元素比第一个元素大,进行数据交换。

       (2)指针向后移动,即使i=i+1,再次比较元素arr[i]和arr[i+1],判断是否需要交换数据。

       (3)针对序列中每一对两两相邻的数据重复以上步骤,直到指针指向最后一个位置。

       (4)在每一轮循环中重复以上步骤(1)(2)(3),直到n-1轮循环执行完毕。

       例如有下面一组数据,按从小到大排序,冒泡排序的过程如下所示。

       第一轮排序:

         第一轮:

        最大值已

       到最后

       第二轮排序完成,则这组数据排序完成,这就是冒泡排序过程。


2、冒泡排序优化

       在冒泡排序过程中,经常会出现这样的情况,经过某一轮交换后就得到了一个有序序列,但循环还在继续,做了很多无用功。例如在上述冒泡排序过程中,当26与8交换后就得到了一个升序序列,但接下来,还是将26与86比较了一下。

       要解决这种消耗,可以设置一个简单的标志位将算法优化。

       

       

       

快速排序

       

       快速排序的基本思想是:通过一趟排序,将序列中的数据分割为两部分,其中一部分的所有数值都比另一部分的小;然后按照此种方法,对两部分数据分别进行快速排序,直到参与排序的两部分都有序为止

       对于一个包含n条记录的序列arr[ ],使用快速排序使序列调整为升序序列的基本操作如下:

       (1)设置变量i和变量j,分别记录序列中第一条记录和最后一条(n-1)记录对应的下标,使用变量key记录序列中第一条记录的键值,即使key=arr[0];

       (2)若i<j成立

                  a. 比较arr[j]和key,若key>arr[j],使arr[i]=arr[j];否则从后往前移动j,

                       即使j--;

                  b.比较arr[i]和key,若key<arr[i],使arr[j]=arr[i];否则从前往后移动i,

              即使i++;

       (3)重复上述步骤(2),直到i<j不成立为止,此时使arr[i]=key。

 

       插入排序(insertion sort)可以视为两步操作,一步是插入,一步是排序。插入排序的基本思想就是将一条记录插入到一组已经有序的序列中,继而得到一个有序的、数据个数加一的新的序列。


直接插入排序


       直接插入排序(straight insertion sort)把待排序序列视为两部分:一部分为有序序列,通常在排序开始之时将序列中的第一个数据视为一个有序序列;另一部分为待排序序列,有序序列之后的数据视为待排序序列。


折半插入排序


       折半插入排序(binary insertion sort)是对直接插入排序的改进。在直接插入排序中,主要的时间消耗在数据的比较和移动上,那么可以在前半部分有序序列中采用折半查找的方法来提高查找速度。

       以数组arr[]为例,在将arr[]排列为一个降序序列的过程中,寻找插入点的具体操作如下:

       (1)分别使用low记录有序序列首位元素下标,high记录有序序列末尾元素下标,tmp记录待插入元素的数据;

       (2)若low<=high,将arr[tmp]与arr[m]作比较,其中m=(low+high)/2:

                a. 若tmp<arr[m],使low=m+1;

                b. 若tmp>=arr[m],使high=m-1;

       (3)重复步骤(2),直到low<=high不成立,此时找到插入点,其下标为high+1。

 

希尔排序


       希尔排序的基本思想是:先取定一个小于n的整数d1作为第一个增量,把序列的全部元素分成d1个组,所有相互之间距离为d1整数倍的元素放在同一个组中,在各组内进行直接插入排序;然后,取第二个增量d2(d2<d1),重复上述的分组和排序过程,直至所取的增量dt=1(dt<dt-1<…<d2<d1),即所有元素放在同一组中进行直接插入排序。

 

 

       选择排序(selection sort)的基本思想是:从待排序的序列中选出最大值(或最小值),交换该元素与待排序序列头部元素,直到所有待排序的数据元素排序完毕为止。

 

简单选择排序


       简单选择排序是最基础的一种选择排序,这种排序方法严格贴合选择排序基本思想。与直接插入排序类似,简单选择排序也可以将序列视为两部分,

只是直接插入排序初始的有序序列有一个元素,简单选择排序初始的整个序列都视为待排序序列,有序序列为空。

 若要使用简单选择排序使数组arr[n]成为一个降序序列,使用i记录当前需要选择最值的位置;使用max记录当前已参与比较的元素中最大值对应的下标,其操作过程如下:

(1)在第m轮比较中,i=m-1,使max=i,即记录当前需要选择最大值的位置,同时初始化j=i+1;

(2)比较arr[max]与arr[j]:

        a) 若arr[max]>arr[j],不进行赋值操作;

        b) 若arr[max]<arr[j],使max= j;

(3)j=j+1。

(4)循环执行步骤(2)(3),直到j<n不成立。此时max记录的值为arr[i]~arr[n-1]中的最大值对应的下标,交换arr[i]与arr[max]。

(5)i=i+1,若i<n-1成立,重复上述步骤(1)~(4),进入下一轮循环。

树形选择排序(tree selection sort)又称锦标赛排序(tournament sort),是一种按照锦标赛思想进行选择排序的方法。

锦标赛的比赛过程很简单:首先所有参加比赛的选手两两分组,每组产生一个胜利者;其次这些胜利者再两两分组进行比赛,每组产生一个胜利者;之后重复执行上一步骤,直到最后只有一个胜者产生为止。

 

树形选择排序的目的不是选出最值,而是通过这种结构经过选择排序获取一个有序序列。二叉树中叶子结点从左至右可以视为原始序列。以锦标赛比赛规则为基础,使用树形选择排序的过程如下:

(1)首先使树中n个叶子结点代表的记录中的关键字两两分组进行比较;

(2)其次使其中⌈n/2⌉个较大者再次两两分组并比较;

(3)如此重复,直到选出当前序列中关键字最大的记录为止;

(4)当一轮比较结束,序列中的最大值会处在根节点的位置。输出并保存根节点,并使其余记录再次重复上述步骤(1)(2)(3)(4)。

 





以上是关于数据结构--排序的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(15)---排序(冒泡排序, 快速排序, 归并排序, 计数排序)

数据结构与算法——排序算法

《数据结构与算法之美》10——排序桶排序计数排序基数排序

[数据结构]排序——八大排序

数据结构的排序方法都有哪些?

数据结构——第八章 排序