各种排序算法及其复杂度分析
文章目录
插入排序
每步将一个待排序的元素,按其排序码大小,插入到前面已经排好序的一组元素的适当位置上, 直到元素全部插入为止
直接插入排序
基本思想
当插入第 i ( i ≥ 1 ) i (i≥1) i(i≥1) 个元素时,前面的 V [ 0 ] , V [ 1 ] , … , V [ i − 1 ] V[0], V[1], …, V[i-1] V[0],V[1],…,V[i−1]已经排好序。这时,用 V [ i ] V[i] V[i]的排序码与 V [ i − 1 ] , V [ i − 2 ] , … V[i-1], V[i-2], … V[i−1],V[i−2],…的排序码顺序进行比较,插入位置即将V[i]插入,原来位置上的元素向后顺移
图解
代码实现
#include "dataList.h"
template <class T>
void InsertSort (dataList<T>& L, int left, int right) {
//依次将元素L.Vector[i]按其排序码插入到有序表
//L.Vector[left],…,L.Vector[i-1]中,使得
//L.Vector[left]到L.Vector[i]有序。
Element<T> temp; int i, j;
for (i = left+1; i <= right; i++)
if (L[i] < L[i-1]) {
temp = L[i]; j = i-1;
do {
L[j+1] = L[j]; j--;
} while (j >= left && temp < L[j]);
L[j+1] = temp;
}
};
算法分析
设待排序元素个数为 c u r r e n t S i z e = n currentSize = n currentSize=n, 则该算法的主程序执行 n − 1 n-1 n−1趟。
排序码比较次数和元素移动次数与元素排序码的初始排列有关。
最好情况下,排序前元素已按排序码从小到大有序,每趟只需与前面有序元素序列的最后一个元素比较1次,总的排序码比较次数为 n − 1 n-1 n−1, 元素移动次数为0。
最坏情况下, 第 i i i 趟时第 i i i 个元素必须与前面 i i i 个元素都做排序码比较, 并且每做1次比较就要做1次数据移动。则总排序码比较次数 K C N KCN KCN和元素移动次数 R M N RMN RMN分别为
平均情况下排序的时间复杂度为 o ( n 2 ) o(n^2) o(n2)。
直接插入排序是一种稳定的排序方法。
折半插入排序
基本思想
设在顺序表中有一 个元素序列 V [ 0 ] , V [ 1 ] , … , V [ n − 1 ] V[0], V[1], …, V[n-1] V[0],V[1],…,V[n−1]。其中, V [ 0 ] , V [ 1 ] , … , V [ i − 1 ] V[0], V[1], …, V[i-1] V[0],V[1],…,V[i−1] 是已经排好序的元素。在插入 V [ i ] V[i] V[i] 时, 利用折半搜索法寻找 V [ i ] V[i] V[i] 的插入位置。
代码实现
#include "dataList.h"
template <class T>
void BinaryInsertSort (dataList<T>& L,
const int left, const int right) {
//利用折半搜索, 在L.Vector[left]到L.Vector[i-1]中
//查找L.Vector[i]应插入的位置, 再进行插入。
Element<T> temp;
int i, low, high, middle, k;
for (i = left+1; i <= right; i++) {
temp = L[i]; low = left; high = i-1;
while (low <= high) {
//折半搜索插入位置
middle = (low+high)/2; //取中点
if (temp < L[middle]) //插入值小于中点值
high = middle-1; //向左缩小区间
else low = middle+1; //否则, 向右缩小区间
}
for (k = i-1; k >= low; k--) L[k+1] = L[k];
//成块移动,空出插入位置
L[low] = temp; //插入
}
};
算法分析
折半搜索比顺序搜索快, 所以折半插入排序就
平均性能来说比直接插入排序要快。
它所需的排序码比较次数与待排序元素序列的初始排列无关,仅依赖于元素个数。在插入第 i i i 个元素时,需要经过 l o g 2 i + 1 log_2i+1 log2i+1次排序码比较, 才能确定它应插入的位置。因此,将 n n n个元素(为推导方便, 设为 n = 2 k n=2k n=2k) 用折半插入排序所进行的排序码比较次数为:
折半插入排序是一个稳定的排序方法
当 n n n较大时,总排序码比较次数比直接插入排序的最坏情况要好得多,但比其最好情况要差。
在元素的初始排列已经按排序码排好序或接近有序时,直接插入排序比折半插入排序执行的排序码比较次数要少。折半插入排序的元素移动次数与直接插入排序相同,依赖于元素的初始排列。
希尔排序
希尔排序方法又称为缩小增量排序。该方法的基本思想是 : 设待排序元素序列有 n n n 个元素, 首先取一个整数 g a p < n gap < n ga