各种排序算法及其复杂度分析

本文详细介绍了各种排序算法,包括直接插入排序、折半插入排序、希尔排序、快速排序、堆排序和归并排序。针对每种排序算法,阐述了其基本思想、代码实现及算法分析,特别是复杂度比较,揭示了它们在不同场景下的性能差异。
摘要由CSDN通过智能技术生成

各种排序算法及其复杂度分析

插入排序

每步将一个待排序的元素,按其排序码大小,插入到前面已经排好序的一组元素的适当位置上, 直到元素全部插入为止

直接插入排序

基本思想

当插入第 i ( i ≥ 1 ) i (i≥1) i(i1) 个元素时,前面的 V [ 0 ] , V [ 1 ] , … , V [ i − 1 ] V[0], V[1], …, V[i-1] V[0],V[1],,V[i1]已经排好序。这时,用 V [ i ] V[i] V[i]的排序码与 V [ i − 1 ] , V [ i − 2 ] , … V[i-1], V[i-2], … V[i1],V[i2],的排序码顺序进行比较,插入位置即将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 n1趟。
排序码比较次数和元素移动次数与元素排序码的初始排列有关。
最好情况下,排序前元素已按排序码从小到大有序,每趟只需与前面有序元素序列的最后一个元素比较1次,总的排序码比较次数为 n − 1 n-1 n1, 元素移动次数为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[n1]。其中, V [ 0 ] , V [ 1 ] , … , V [ i − 1 ] V[0], V[1], …, V[i-1] V[0],V[1],,V[i1] 是已经排好序的元素。在插入 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 &lt; n gap &lt; n ga

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值