(1)冒泡排序
相邻的两个元素比较,后者大则交换位置。共循环n次,第i次需要比较n-i个元素。稳定排序。
所以比较的时间复杂度为(n-1)+...+1=(n-1)*n/2=n*n
(2)选择排序
给每个位置选择当前元素最小的,比如给第一个位置选择最小的(将最小的值和第一个位置的值互换位置),在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
所以比较的时间复杂度为(n-1)+...+1=(n-1)*n/2=n*n
(3)插入排序(分为直接插入(n*n/2)、二分插入(n*logn)、表插入(n*n/2)、Shell排序)
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
(4)快速排序
快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j,交换a[i]和a[j],重复上面的过程,直到i > j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。
使用分治法(类似二叉排序树):
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
复杂度O(N*logN)
(5)归并排序
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。
时间复杂度为n*logn,辅助空间为n
(6)基数排序
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。
(7)希尔排序(shell)
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。
(8)堆排序
我们知道堆的结构是节点i的孩子为2 * i和2 * i + 1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n / 2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n / 2 - 1, n / 2 - 2, ... 1这些个父节点选择元素时,就会破坏稳定性。有可能第n / 2个父节点交换把后面一个元素交换过去了,而第n / 2 - 1个父节点把后面一个相同的元素没 有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。
步骤:先建堆,再排序。其中,建堆是从所给序列的size/2开始->第一个元素26,其实是倒数第二层开始,依次与下面所有子节点比较。建堆完成后,拿根节点(即最大值)与最小节点互换位置,再排序,依次类推。
建堆比较的复杂度为4n~=n,然后排序负责度为2log(n-1)+...+2log(1)=nlogn,所以最终复杂度为n*logn
其中,稳定排序和非稳定排序的区别是,对于相同元素的处理,排序后,相同元素之间的相对位置会不会发生改变。不改变则叫作稳定。
综上,得出结论: 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法
相关推荐
关于数据的几种排序算法的程序对比分析,结合具体案例
本文将深入探讨由C语言实现的几种常见排序算法,包括它们的基本原理、实现细节和性能特点。 首先,让我们从最经典的排序算法——冒泡排序(Bubble Sort)开始。冒泡排序通过不断地交换相邻的不正确顺序的元素来逐步...
根据给定文件中的标题、描述、标签以及部分内容,我们可以总结出以下关于几种排序算法的知识点,特别是关于希尔排序的相关细节。 ### 几种排序算法的代码实现 #### 1. **希尔排序** - **定义与原理**:希尔排序是...
下面我们将详细解析链表实现的几种排序算法,以及它们的优缺点。 1. **冒泡排序** (LinkList1.cpp 和 LinkList2.cpp): 冒泡排序是一种简单的交换排序,通过不断比较相邻元素并交换位置,使较大的元素逐渐"浮"到...
这里我们将深入探讨几种最常见的排序算法,包括冒泡排序、选择排序、插入排序、快速排序以及归并排序。 1. 冒泡排序(Bubble Sort) 冒泡排序是最基础的排序算法之一,它通过不断地比较相邻元素并交换位置来实现...
C++中的几种排序算法 C++中的几种排序算法是计算机科学中的一种基本算法,用于对数据进行排序。排序算法的选择取决于具体的应用场景和数据特点。本文将介绍C++中的几种常见的排序算法,包括插入排序、选择排序、...
以下是对标题和描述中提及的几种排序算法的详细解释: 1. **Shell排序**:由Donald Shell于1959年提出,是一种改进的插入排序。它通过将待排序的元素按一定的间隔分组,然后对每组进行插入排序,逐渐减小间隔,直到...
本文将详细介绍Java中常见的几种排序算法,包括冒泡排序、快速排序以及选择排序。 1. **冒泡排序**: 冒泡排序是最基础的排序算法之一,它的主要思想是通过不断比较相邻元素并交换位置,使得较大的元素逐渐“浮”到...
该程序包含了几种算法,读者可对此进行试验
本资源"**C语言几种排序算法实现.zip**"可能包含了一系列用C语言编写的经典排序算法,如冒泡排序、插入排序、选择排序、快速排序、归并排序和堆排序等。下面将对这些常见的排序算法进行详细介绍。 1. **冒泡排序...
根据给定文件的内容,以下是对学习的几种排序算法的详细知识点总结。 1. 冒泡排序(BubbleSort): 冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换...
在这篇《基于C语言的几种排序算法的分析》的研究论文中,作者陈思敏对计算机程序设计中常见的几种排序算法进行了深入的分析。文中讨论了排序算法的概念、特点、C语言实现方法以及算法的时间复杂度,还对这些排序算法...
### 数据结构中几种排序算法分析比较 #### 插入排序 **插入排序**是一类简单直观的基于比较的排序算法。其基本思想是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 #####...
这个文件"JAVA关于几种排序算法的性能比较.pdf"显然探讨了不同排序算法在Java环境下的效率对比,包括直接插入排序、直接选择排序、冒泡排序、希尔排序、快速排序和堆排序。这些排序算法各有优劣,适用于不同的场景,...
本程序主要演示了归并,插入,快排等几种排序算法在各种不同数据量的情况下的算法效率,适合编程新手对排序算法的认识和学习
7种排序算法程序汇总 冒泡排序 选择排序 插入排序 希排序尔 快速排序 二叉排序树 堆排序
PHP中的几种排序算法 一、 开发环境 1、环境搭建:Windows 7+Apache 2.4.18+MySQL 5.7.11+PHP 7.1.0。 2、文本编辑器:Sublime 3。 二、主要技术 本案例主要使用PHP 7中的几种排序算法:快速排序、选择排序、插入...