当前位置: 首页 > article >正文

【从零开始学习计算机科学】算法分析(二)排序算法 与 分治法

【从零开始学习计算机科学】算法分析(二)排序算法 与 分治法

  • 排序算法
    • 插入排序
    • 冒泡排序
    • 快速排序
    • 希尔(Shell)排序
    • 选择排序
    • 堆排序
    • 归并排序
    • 计数排序
    • 基数排序
    • 桶排序
  • 分治法

排序算法

这一部分主要介绍一些常用的基础排序算法,并从稳定性,时间、空间复杂度进行分析。

插入排序

插入排序将待排序的数据分成两个区域:有序区和无序区,每次将一个无序区中的数据按其大小插入到有序区中的适当位置,直到所有无序区中的数据都插入完成为止。

伪代码如下:

void insertsort(Elemtype a[], int n){
    int i, j;
    for(int i = 2; i<=n; i++){
        if(a[i] < a[i-1]){
            a[0] = a[i];
            for(int j = i-1; a[0] < a[j]; --j){
                a[j+1] = a[j];
            }
            a[j+1] = a[0];
        }
    }
}

分析:稳定性:稳定;时间复杂度:O( n 2 n^2 n2);空间复杂度:O(1)。

冒泡排序

冒泡排序最多进行n-1趟排序,每趟排序时,按相同的方向扫描,一旦发现两个相邻的元素不符合规则,则交换。

伪代码如下:

void bubblesort(Elemtype a[], int n){
    for(int i = 0; i<n-1; i++){
        for(int j = 0; j<n-1-i; j++){
            if(a[j] < a[j+1]){
                swap(a[j], a[j+1]);
            }
        }
    }
}

分析:稳定性:稳定;时间复杂度:O( n 2 n^2 n2);空间复杂度:O(1)。

改进方法:每趟排序时,记住最后一次发生交换的位置,则该位置之前的记录均已有序。

快速排序

在A[1, … \ldots ,n]中任取一个数据元素作为比较的基准(记为X),将数据区划分为左右两个部分:A[1, … \ldots ,i-1]和A[i+1, … \ldots ,n],且A[1, … \ldots ,i-1] ≤ \leq X ≤ \leq A[i+1, … \ldots ,n](1 ≤ \leq i ≤ \leq n),当A[1, … \ldots ,i-1]和A[i+1, … \ldots ,n]非空时,分别对它们进行上述的划分过程,直至所有数据元素均已排序为止。

伪代码如下:

int partition(Elemtype a[], int low, int high){
    Elemtype p = a[low];
    while(low < high){
        while(high>low && a[high]>=p) high--;
        a[low] = a[high];
        while(low<high && a[low]<=p) low++;
        a[high] = a[low];
    }
    a[low] = p;
    return low;
}

void quicksort(Elemtype a[], int low, int high){
    if(low < high){
        int mid = partition(a, low, high);
        quicksort(a, low, mid-1);
        quicksort(a, mid+1, high);
    }
}

分析:稳定性:不稳定。

时间复杂度:每趟排序所需的比较次数为待排序区间的长度-1,排序趟数越多,占用时间越多。

最坏情况:每次划分选取的基准恰好都是当前序列中的最小(或最大)值,划分的结果A[low, … \ldots ,i-1]为空区间 或A[i+1, … \ldots ,high]是空区间,且非空区间长度达到最大值。这种情况下,必须进行n-1趟快速排序,第i次趟区间长度为n-i+1,总的比较次数达到最大值:n(n-1)/2 = O( n 2 n_2 n2)。

最好情况:每次划分所取的基准都是当前序列中的“中值”,划分后的两个新区间长度大致相等。共需lgn趟快速排序,总的关键字比较次数:O(n·lgn)。

平均情况:根据主定理可以得到,平均时间复杂度为O(n·lgn)。
基准的选择决定了算法性能。经常采用选取low和high之间一个随机位置作为基准的方式改善性能。

空间复杂度:快速排序在系统内部需要一个栈来实现递归,最坏情况下为O(n),最佳情况下为O(lg·n)。

希尔(Shell)排序

希尔排序任取一个小于n的整数 S 1 S_1 S1作为增量,把所有元素分成 S 1 S_1 S


http://www.kler.cn/a/593122.html

相关文章:

  • Python与Web 3.0:重新定义数字身份验证的未来
  • C# HTTP认证方式详解与代码实现
  • 日常用命令
  • SAP的WPS导出找不到路径怎么办;上载报错怎么办
  • Could not create directory ‘/c/Users/.ssh‘ (No such file or directory).
  • python 数据可视化matplotib库安装与使用
  • 【SpringMVC】深入解析 API 概念及接口定义方法和 SpringMVC 综合实战—简单加法计算器
  • 革新协作体验 | 集和诚KMDA-2631协作机器人控制器重磅上市!
  • [数据结构]排序之 堆排序详解
  • 先有OLE还是先有COM?
  • xss漏洞基础整理
  • podspec语法
  • MyBatis 传递多个参数的方式
  • 原生JavaScript控制页面跳转的几种方式
  • git tag常用操作
  • Springboot项目打包成war包
  • AJAX PHP:深入理解与实际应用
  • 基于SpringBoot + Vue 的药店药品信息管理系统
  • 基于Spring Boot的本科生交流培养管理平台的设计与实现(LW+源码+讲解)
  • QT--按键事件与定时器事件