七、排序算法

一、排序的概念与分类

排序的一般定义

 排序是计算机内经常进行的一种操作 , 其目的是将一组“ 无序” 的数据元素调整为“ 有序” 的数据元素。

例如 : 将下列关键字序列
52, 49, 80, 36, 14, 58, 61, 23, 97, 75
调整为
14, 23, 36, 49, 52, 58, 61 ,75, 80, 97

排序的数学定义
 假设含有n个数据元素的序列为{R1 , R2 , …, Rn },其相应的关键字序列为{ K1 , K2 , …, Kn },这些关键字相互之间可以进行比较 , 即在它们之间存在着这样一个关系:
Kp1 <= Kp2 <= …<=Kpn
按此固有关系将上式记录序列重新排列为
{ R p1 , R p2 , … ,R pn }
的操作称作 排序 。
排序的稳定性
如果在序列中有两个数据元素r[i]和r[j],它们的关键字k[i ] ==k[j],且在排序之前,对象r[i]排在r[j]。 如果在排序之后 , 对象r[i]仍在对象r[j]的前面, 则称这个排序方法是稳定的。
多关键字排序

排序时需要比较的关键字多余一个
排序结果首先按关键字 1 进行排序
当关键字 1 相同时按关键字 2 进行排序
……
当关键字 n-1 相同时按关键字 n 进行排序

排序中的关键操作

比较:任意两个数据元素通过比较操作确定先后次序
交换: 数据元素之间需要交换才能得到预期结果

内排序和外排序

内排序:整个排序过程不需要访问外存便能完成
外排序:待排序的数据元素数量很大 , 整个序列的排序过程不可能在内存中完成

排序的审判

时间性能:关键性能差异体现在比较和交换的数量
辅助存储空间:为完成排序操作需要的额外的存储空间;必要时可以“ 空间换时间”
算法的实现复杂性:过于复杂的排序法会影响代码的可读性和可维护性 , 也可能影响排序的性能

二、基本的排序算法

选择排序
每一趟 ( 例如第i趟 , i = 0, 1, … , n- 2)在后面n-i 个待排的数据元素中选出关键字最小的元素 , 作为有序元素序列的第 i 个元素。

插入排序
当插入第i(i>=1)个数据元素时,前面的V[0], V[1], … , V[i-1]已经排好序 。 这时 ,用 V[i]的关键字与 V[i-1], V[i-2], … 的关键字进行比较 , 找到插入位置即将 V[i]插入 , 原来位置上的对象向后顺移。

冒泡排序
设待排数据元素序列中的元素个数为 n。最多作 n-1趟,i = 1, 2, … … , n-1。在第 i 趟中从后向前, j = n-1, n-2, … … , i, 两两比较 V[j-1] 和 V[j]的关键字。如果发生逆序, 则交换 V[j-1] 和 V[j]。

希尔排序
将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序列进行插入排序。

将n个数据元素分为d个子序列:
{R[1],R[1+d],R[1+2d],…,R[1+kd]}
{R[2],R[2+d],R[2+2d],…,R[2+kd]}
...
{R[d],R[2+d],R[3+2d],…,R[(k+1)d]}

其中,d称为增量,它的值在排序过程中从大到小逐渐缩小,直至最后一趟排序减为1.

快速排序
1) 任取待排序序列中的某个数据元素( 例如: 第一个元素) 作为基准, , 按照该元素的关键字大小将整个序列划分为左右两个子序列:
 左侧子序列中所有元素都小于或等于基准元素
 右侧子序列中所有元素都大于基准元素
 基准元素排在这两个子序列中间
2) 分别对这两个子序列重复施行上述方法,直到所有的对象都排在相应位置上为止 。

归并排序
将两个或两个以上的有序序列合并成一个新的有序序列
V[1] … V[m]和V[ m +1] … V[n] -------------------> V[1] … V[n]
这种归并方法称为2路归并。

总结:
希尔排序 , 快速排序和归并排序将排序算法的时间复杂度提高到了 O(n*logn)
希尔排序和快速排序的排序结果是不稳定的
算法实现源码

原文地址:https://blog.51cto.com/yinsuifeng/2415507

时间: 2024-10-19 12:20:29

七、排序算法的相关文章

模板化的七种排序算法,适用于T* vector&lt;T&gt;以及list&lt;T&gt;

最近在写一些数据结构以及算法相关的代码,比如常用排序算法以及具有启发能力的智能算法.为了能够让写下的代码下次还能够被复用,直接将代码编写成类模板成员函数的方式,之所以没有将这种方式改成更方便的函数模板纯属于偷懒,更方便于测试代码的有效性,等代码写完也懒得去改了.下面开始介绍这段代码,有什么不对的地方欢迎前来指正. 一共写了七种排序,插入排序InsertSort.堆排序HeapSort.快速排序QuickSort.合并排序MergeSort,计数排序CountingSort,基数排序RadixSo

七种常用排序算法

七种常用排序算法 一.常见排序算法一览: 时间复杂度: 是一个函数,它定量描述了该算法的运行时间. 空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度. 稳定性:保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同就稳定,反之不稳定. 视觉直观感受 7 种常用的排序算法 二.算法C#实现: 1. 直接插入排序: using System; using System.Collections.Generic; using System.Linq; using Sys

排序算法七:选择排序之堆排序

排序算法七:选择排序之堆排序 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 引言 在我的博文<"主宰世界"的10种算法短评>中给出的首个算法就是高效的排序算法.本文将对排序算法做一个全面的梳理,从最简单的"冒泡"到高效的堆排序等. 上博文讲述了选择排序中的简单排序算法,本文介绍的堆排序是树性选择排序,采用堆这个数据结构来辅助排序. 排序相关的的基本概念 排序:将一组杂乱无章的数据按一定的规律顺次排列起来. 数据

七种经典排序算法最全攻略

经典排序算法在面试中占有很大的比重,也是基础.包括冒泡排序,插入排序,选择排序,希尔排序,归并排序,快速排序,堆排序.希望能帮助到有需要的同学.全部程序采用JAVA实现. 本篇博客所有排序实现均默认从小到大. 一.冒泡排序 BubbleSort 介绍: 冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来. 步骤: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对第0个到第n-1个数据做同样的工作.这时,最大的数就"浮"到了

排序算法七:基数排序(Radix sort)

上一篇提到了计数排序,它在输入序列元素的取值范围较小时,表现不俗.但是,现实生活中不总是满足这个条件,比如最大整形数据可以达到231-1,这样就存在2个问题: 1)因为m的值很大,不再满足m=O(n),计数排序的时间复杂也就不再是线性的: 2)当m很大时,为计数数组申请的内存空间会很大: 为解决这两个问题,本篇讨论基数排序(Radix sort),基数排列的思想是: 1)将先按照某个基数将输入序列的每个元素划分成若干部分,每个部分对排序结果的影响是有优先级的: 2)先按低优先级排序,再按高优先级

复习数据结构:排序算法(七)——桶排序

桶排序是一种稳定的排序方法,也是一种外排序. 桶排序的时间复杂度:最坏情况运行时间:当分布不均匀时,全部元素都分到一个桶中,则O(n^2),当然[算法导论8.4-2]也可以将插入排序换成堆排序.快速排序等,这样最坏情况就是O(nlgn).最好情况运行时间:O(n). 也就说,前面介绍的排序算法要么是O(n^2),要么是O(nlogn),只有桶排序是可能实现O(n)排序的,但是对数据是有要求的. 基本思想:是将阵列分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续

七种常见经典排序算法总结(C++)

最近想复习下C++,很久没怎么用了,毕业时的一些经典排序算法也忘差不多了,所以刚好一起再学习一遍. 除了冒泡.插入.选择这几个复杂度O(n^2)的基本排序算法,希尔.归并.快速.堆排序,多多少少还有些晦涩难懂,幸好又博客园大神dreamcatcher-cx都总结成了图解,一步步很详细,十分感谢. 而且就时间复杂度来说,这几种算法到底有什么区别呢,刚好做了下测试. 代码参考: http://yansu.org/2015/09/07/sort-algorithms.html //: basic_so

排序算法(七)非比较排序:计数排序、基数排序、桶排序

前面讲的是比较排序算法,主要有冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等. 非比较排序算法:计数排序,基数排序,桶排序.在一定条件下,它们的时间复杂度可以达到O(n). 一,计数排序(Counting Sort) (1)算法简介 计数排序(Counting sort)是一种稳定的排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置.它只能对整数进行排序. (2)算法描述和实现 得到待排序数的范围(在

【整理】常见排序算法及其时间复杂度总结

原文出处: 1. 白话经典算法系列之八 MoreWindows白话经典算法之七大排序总结篇 2. 面试常用算法总结--排序算法(java版) 3. 常见排序算法小结 本篇主要整理了冒泡排序,直接插入排序,直接选择排序,希尔排序,归并排序,快速排序,堆排序七种常见算法,是从上面三篇博文中摘抄整理的,非原创. 一.冒泡排序 主要思路是: 通过交换相邻的两个数变成小数在前大数在后,这样每次遍历后,最大的数就"沉"到最后面了.重复N次即可以使数组有序. 冒泡排序改进1: 在某次遍历中,如果没有