排序算法性能对比

这是我参与18月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

分类 最好时间复杂度 平均时间复杂度 最坏时间复杂度 空间复杂度 稳定情况
直接插入排序 O(n) O(n^2) O(n^2) O(1) 稳定
希尔排序 不稳定
选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定
堆排序 O(nlog2n) O(nlog2n) O(nlog2n) O(1) 不稳定
冒泡排序 O(n) O(n^2) O(n^2) O(1) 稳定
快速排序 O(nlog2n) O(nlog2n) O(n^2) O(log2n) 稳定
归并排序 O(nlog2n) O(nlog2n) O(nlog2n) O(n) 稳定

上面主要对比的是排序算法的算法性能分析对比。

其中关于一个算法是否稳定是如何判断的:

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的(来自百度百科)简单来说:假设两个待排序的元素位置a和b 且a在b的前面 位置上对应的关键字是相等的 在排序后他们的相对位置不变则为稳定的

  • 直接插入排序 最好的情况就是直接在其后面插入,最坏的情况就是逆序 每次插入都要循环n遍 (这耶可以看出 待排序列越有序 效率就越高 )

  • 选择排序

要选数据再把选好的数据放在后面 所以无论序列是否有序时间复杂度都是n^2

  • 希尔排序 (缩小增量排序)

他是不稳定的 因为根据希尔排序的过程我们可以看到 每次他是以一个增量来选择一个分组 在这个分组中进行排序 则相对位置就有可能改变

  • 冒泡排序

当数据有序是 其不用进行交换 只需要遍历一遍序列即可,但若数据无序 则需要的时间复杂度就是n^2 因为冒泡排序主要是对小于或则大于的数据才会进行交换 所以是稳定的算法

  • 快速排序

他的性能好坏主要是对于取这个基准数据要选的好 所以他最好也要nlog2n

  • 堆排序
//建堆
void BuildMaxHeap(ElementType A[], int len) { 
      for (int i = len / 2; i > 0; i--) { 
      HeadAdjust(A, i, len);
      }
}

//调整为大顶堆
void HeadAdjust(ElementType A[], int k, int len) {
  A[0] = A[k];
  for (int i = 2 * k; i <= len; i *= 2) {
    if (i < len && A[i] < A[i + 1]) {i++;}
    if (A[i] <= A[0]) break;
    else {
      A[k] = A[i];
      k=i;
    }
  }
  A[k] = A[0];
}

//堆排序 不断调整位置
void HeapSort(ElementType A[], int len) {
  BuildMaxHeap(A, len);
  for (int i = len; i > 1; i--){
    swap(A[i], A[1]); //交换位置
    HeadAdjust(A, 1, i - 1);
  }
  
}
复制代码

从上面的代码进行分析 我们建堆 从最后一个非叶子结点向根结点遍历(倒着录)判断其左右子树是否需要调整 调整完后又向上进行比对 调整直到比对到根结点 以此类推 所以根据这个代码可知其时间复杂度为nlog2n

猜你喜欢

转载自juejin.im/post/7033327585413038088