排序算法的复杂度及稳定性详解(内含记忆小窍门)

news2024/11/26 4:25:52

排序算法的复杂度及稳定性

  • 一、排序算法分类
  • 二、概念
    • 2.1 时间复杂度
    • 2.2 空间复杂度
    • 2.3 稳定性
  • 三、表格比较
    • 注意
  • 四、部分排序分析
    • 4.1 直接插入排序
      • 图示
      • 代码
    • 4.2 冒泡排序
      • 图示
      • 代码
    • 4.3 快速排序
      • 图示
      • 代码
  • 五、结构化记忆(小窍门)
    • 5.1 结构化
    • 5.2 我的结构化
  • 六、总结

一、排序算法分类

在这里插入图片描述

二、概念

算法的复杂性体现在运行该算法时的计算机所需资源的多少,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度。

2.1 时间复杂度

是一个定性描述该算法的运行时间的函数。
作用: 指执行算法所需要的计算工作量。

2.2 空间复杂度

是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。
比如直接插入排序的时间复杂度是O(n2),空间复杂度是O(1) 。而一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。

2.3 稳定性

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

三、表格比较

在这里插入图片描述

注意

1:希尔排序的平均时间复杂度,还有一种表示为O(n1.3)
2:基数排序时间复杂度O(N*M),其中N为数据个数,M为数据位数。
3:归并排序可以通过手摇算法将空间复杂度降到O(1),但是时间复杂度会提高。
4:关于logn的底数看下面的解释
5:分治法和树形,时间复杂度是nlogn
在这里插入图片描述

四、部分排序分析

正序选择插入和冒泡,只比较,不交换反之,倒序时尽量不选择插入和冒泡
有序时尽量不选择快排,因为使用不到分治。

4.1 直接插入排序

图示

在这里插入图片描述

代码

public class InsertSort {
    //核心代码---开始
    public static void sort(Comparable[] arr){

        int n = arr.length;
        for (int i = 0; i < n; i++) {
            // 寻找元素 arr[i] 合适的插入位置
            for( int j = i ; j > 0 ; j -- )
                if( arr[j].compareTo( arr[j-1] ) < 0 )
                    swap( arr, j , j-1 );
                else
                    break;
        }
    }
    //核心代码---结束
    private static void swap(Object[] arr, int i, int j) {
        Object t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static void main(String[] args) {

        Integer[] arr = {1,9,6,5,7,6,8,2,4};
        sort(arr);
        for( int i = 0 ; i < arr.length ; i ++ ){
            System.out.print(arr[i]);
            System.out.print(' ');
        }
    }
}

4.2 冒泡排序

图示

在这里插入图片描述

代码

//冒泡排序
void BubbleSort(int* arr, int n)
{
	int end = n;
	while (end)
	{
		int flag = 0;
		for (int i = 1; i < end; ++i)
		{
			if (arr[i - 1] > arr[i])
			{
				int tem = arr[i];
				arr[i] = arr[i - 1];
				arr[i - 1] = tem;
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
		--end;
	}
}

4.3 快速排序

图示

在这里插入图片描述
在这里插入图片描述

代码

void Quick_Sort(int *arr, int begin, int end){
    if(begin > end)
        return;
    int tmp = arr[begin];
    int i = begin;
    int j = end;
    while(i != j){
        while(arr[j] >= tmp && j > i)
            j--;
        while(arr[i] <= tmp && j > i)
            i++;
        if(j > i){
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }
    arr[begin] = arr[i];
    arr[i] = tmp;
    Quick_Sort(arr, begin, i-1);
    Quick_Sort(arr, i+1, end);
}

五、结构化记忆(小窍门)

5.1 结构化


指将逐渐积累起来的知识加以归纳和整理,使之条理化、纲领化,做到纲举目张。知识是逐渐积累的,但在头脑中不应该是堆积的。知识是有组织、有系统的,知识点按层次排列,而且知识点之间有内在联系,具有结构层次性。

5.2 我的结构化

我们都知道数据结构,数据结构指相互之间存在一种或多种特定关系的数据元素的集合,我们也可以把身边一切东西放在一起,去创造它们之间的关系。
现在就给大家分享一下我对七种比较排序的时间复杂度、空间复杂度和稳定性进行的“胡乱”结构化,请结合上面的二维表:
先来看时间复杂度(平均时间复杂度、最好时间复杂度、最坏时间复杂度):
1、找共性:
首先看到有些排序这三个复杂度一样,分别是直接选择排序,堆排序和归并排序,其中直接选择排序、堆排序属于选择排序,我提取了它们的首字母(归并、选择=GX),GX让我想到了共享,这不是刚好符合它们的特征吗,共享同一个时间复杂度。他们三个的区别是,直接选择排序是O(n2),归并和堆排序是nlogn。
2、找联系:
我们顺着nlogn继续往下找,快速排序也是nlogn,但是它不属于第一分类的“共享”,说明三者不一样,那哪个不一样呢,是最坏时间复杂度为n2。(n2>nlogn)
3、排除:
七个排序还剩下三个(冒泡、直接插入和希尔排序),这三个又有什么特点呢?
冒泡、直接插入和希尔排序他们在数组基本有序的情况下,只需要执行n次逻辑代码,最好时间复杂度都是O(n),冒泡、直接插入最坏和平均都是n2。剩下一个希尔,因为有步长,所以比较特殊,单独理解就好。
总结一下整个过程就是:
gx–nlogn–(7-4)–2+1
在这里插入图片描述
再说空间复杂度:找到的共性是大部分都是O(1),只有两个比较特殊,一个是归并,一个是快排,(这个结构化的过程交给你来了,试试吧小伙伴,你会发现很有意思);
稳定性:快选希堆不稳定,其余稳定。

整个过程就是这么有意思~~~~

六、总结

时间复杂度和空间复杂度咋一看确实比较麻烦,如果想要记忆,首先要理解概念,然后要理解每种复杂度代表的含义,最后一点,知识从来不枯燥,想象力创造力可以让本来没有意义的内容变得有意思,包括写代码,所以,不要枯燥的学习了,让我们一起“造”起来吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023 如何备考系统架构师?

高级系统架构设计师难度还是有的&#xff0c;所以一般千万不要裸考&#xff01;&#xff01;要时间充足&#xff0c;至少要接触过&#xff0c;反正没有基础的尽量还是不要去裸考了&#xff01; 一、系统架构设计师考试题型 考试科目分为综合题&#xff08;选择题&#xff09;&a…

Stable Diffusion最全保姆级安装教程(建议收藏)

Midjourney 因细致的画图风格备受大家的欢迎&#xff0c;但由于其网络环境以及会员费&#xff0c;导致入门门槛过高&#xff0c;拦住了很多对AIGC感兴趣的小伙伴。 今天阿良就教大家&#xff0c;不需要魔法&#xff0c;也不用交会员费&#xff0c;尽情玩转AI出图的保姆级安装教…

力扣算法系统刷题详细题解记录二(字符串、双指针法、栈与队列)

力扣算法系统刷题题解记录二&#xff08;字符串、双指针法、栈与队列&#xff09; 前言 参考顺序和资料&#xff1a;《代码随想录》 二刷要认真做笔记啦&#xff0c;加油&#xff01; 笔记模板&#xff1a; #### 解题思路#### 示意图#### 代码四、字符串 344.字符串反转 编…

求最小生成树(Kruskal算法和Prim算法)

目录 一、前言 二、相关概念 1、最小生成树 2、Prim算法&#xff08;对结点进行操作&#xff09; 3、kruskal 算法&#xff08;对边进行操作&#xff09; 三、例题 1、修建公路&#xff08;lanqiaoOJ题号1124&#xff09; 1、Prim算法题解 2、Kruskal算法 一、前言 很…

PyToch 深度学习 || 卷积神经网络分类

卷积神经网络分类 import torch import torch.nn as nn import torchvision import numpy as np from torch.autograd import Variable import matplotlib.pyplot as plt import torch.nn.functional as F import torch.utils.data as Data from torchvision import datasets,…

【业务功能篇20】Springboot java逻辑实现动态行转列需求

在此前&#xff0c;我也写过一个行转列的文章&#xff0c;是用存储过程sql处理的一个动态的逻辑 Mysql 存储过程\Mybatis框架call调用 实现动态行转列 那么后面我们同样又接收了业务的一个新需求&#xff0c;针对的是不同的业务数据&#xff0c;做的同样的一个展示数据报表&…

【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发

文章目录 1. 统一的列表初始化{ } 初始化initializer_list 2. 引用左值引用右值引用左值引用与右值引用的相互转换右值引用的真正使用场景移动构造 C98与C11传值返回问题注意事项总结 3. 完美转发 1. 统一的列表初始化 { } 初始化 C11 扩大了括号括起的列表(初始化列表)的使用…

使用PHP导出Excel时处理复杂表头的万能方法

使用PHP导出Excel时&#xff0c;如果是一级表头处理起来很简单&#xff0c;但如果碰到复杂一点的表头&#xff0c;比如二级、三级&#xff0c;甚至更多级别的表头要怎么办呢&#xff1f; 就像下面这个表头&#xff0c;有三层&#xff0c;并且每层都不太规则—— 难道我们每次处…

动态绑定v-model,并解决输入框无法输入和无法双向绑定问题

问题&#xff1a;在界面中想要动态获取数据库中返回的数据&#xff0c;作为下拉的值&#xff0c;每个下拉值中又包含不同的属性信息&#xff0c;给输入框动态绑定v-model&#xff0c;但是绑定成功后输入框内无法输入内容&#xff0c;且没有双向绑定 解决思路&#xff1a;1.双向…

SIM:基于搜索的用户终身行为序列建模

SIM&#xff1a;基于搜索的用户终身行为序列建模 论文&#xff1a;《Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Through Rate Prediction》 下载地址&#xff1a;https://arxiv.org/abs/2006.05639 1、用户行为序列建模回顾 1…

在 AWS 上使用 OpenText 实现业务关键型应用程序的现代化

通过在云中进行信息管理建立持久的竞争优势 创新在云中发生的速度比以往任何时候都快。 企业面临着数字经济快速转型的挑战&#xff0c;充分释放业务信息的能力对于建立持久的竞争优势至关重要。为分散的员工扩大安全可靠的协作范围将是生产力和创新的关键驱动力。 如今大多…

Web UI自动化测试之元素定位

目前&#xff0c;在自动化测试的实际应用中&#xff0c;接口自动化测试被广泛使用&#xff0c;但UI自动化测试也并不会被替代。让我们看看二者的对比&#xff1a; 接口自动化测试是跳过前端界面直接对服务端的测试&#xff0c;执行效率和覆盖率更高&#xff0c;维护成本更低&am…

【EtherCAT】一、入门基础

什么是EtherCAT&#xff1f; 介绍简介特点和优势EtherCAT系统组成主站从站 硬件EtherCAT主站芯片EtherCAT从站芯片 EtherCAT应用层协议 工具软件 介绍 简介 EtherCAT&#xff08;Ethernet Control Automation Technology&#xff09;是一种高性能实时以太网通信协议&#xff…

Ubuntu20.04设置开机自启动脚本

1.建立开机启动服务 sudo vim /lib/systemd/system/rc-local.service 在末尾添加 [Install] WantedBymulti-user.target Aliasrc-local.service2.创建 /etc/rc.local sudo touch /etc/rc.local && sudo chmod 755 /etc/rc.local #!/bin/bash cd /home/docker-data/ss…

前端框架笔记

Vue.js的安装 安装Vue.js有两种方法&#xff1a; &#xff08;1&#xff09;类似于Bootstrap或jQuery&#xff0c;直接通过HTML文件中的标签引用。为了方便开发者使用&#xff0c;Vue.js提供了相关的CDN&#xff0c;通过如下代码可以引用最新版本的Vue.js&#xff1a; <sc…

小黑回到学校,跟小老黑中老黑阿黄一起度过最后在学校的日子的leetcode之旅:3. 无重复字符的最长子串

双指针动态滑动窗口 class Solution:def lengthOfLongestSubstring(self, s: str) -> int:# 字符串长度n len(s)# 双指针left 0right 0# 存储集合set_ set()# 当前子串长度cur_len 0# 结果result 0# 分别遍历每一个右指针while right < n:# 该字符是重复的&#x…

向量相似搜索绕不开的局部敏感哈希

在搜索推荐中&#xff0c;通常使用相似Embedding进行推荐&#xff0c;此时就会有一个问题&#xff1a;如何快速找到与一个Embedding相近的其他Embedding。 如果两个Embedding在同一个向量空间中&#xff0c;我们就可以通过很多种方式&#xff08;内积、余弦、欧氏距离等&#…

python3 爬虫相关学习8:python 的常见报错内容 汇总收集

目录 1 拼写错误 AttributeError: NameError: 等等 2 类型错误 TypeError: 如字符串连接错误 TypeError: can only concatenate str (not “int“) to str 3 意外缩进 IndentationError: unexpected indent 4 找不到对应模块 ModuleNotFoundError: 5 语法错误 Syntax…

【Docker】deepin/centos安装docker

deepin虚拟机和centos服务器安装docker 1.更新软件包 # deepin sudo apt-get update && sudo apt-get upgrade # centos sudo yum update && yum upgrade安装docker之前&#xff0c;先更新一下软件包 mothramothra-PC:~$ sudo apt-get update && sud…

《Lua程序设计》--学习6

日期和时间 第1种表示方式是一个数字&#xff0c;这个数字通常是一个整型数。尽管并非是ISO C所必需的&#xff0c;但在大多数系统中这个数字是自一个被称为纪元&#xff08;epoch&#xff09;的固定日期后至今的秒数。 Lua语言针对日期和时间提供的第2种表示方式是一个表。日…