经典算法:查找与排序

news2024/11/23 15:13:58

查找

1. 线性查找

算法思想:

线性查找,也被称为顺序查找,是一种最简单的查找算法。它的基本思想是从表的一端开始,逐个检查表中的元素,直到找到所需的元素为止。如果表中不存在该元素,则查找失败。

具体实现:太简单,略过

2.二分查找

算法思想:

二分查找是一种在有序列表中查找某一特定元素的搜索算法。搜索过程从列表的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在列表大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤列表为空,则代表找不到。

具体实现

  • 初始化两个指针(或索引)low和high,分别指向列表的起始和结束位置。
  • 计算中间位置mid。
  • 将中间位置的元素与目标元素进行比较。
    • 如果相等,则返回mid作为目标元素的位置。
    • 如果目标元素大于中间元素,则将low更新为mid+1,继续在右半部分查找。
    • 如果目标元素小于中间元素,则将high更新为mid-1,继续在左半部分查找。
  • 重复步骤2和3,直到找到目标元素或low大于high(表示未找到)。
def binary_search(list, target):
    low = 0
    high = len(list) - 1
    while low <= high:
        mid = (low + high) // 2
        guess = list[mid]
        if guess == target:
            return mid
        elif guess > target:
            high = mid - 1
        else:
            low = mid + 1
    return None  # 返回None表示查找失败

排序

基本排序算法

1.冒泡排序

算法思想:

冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止,这时该数列已经排序完成。

具体实现:

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        # 提前退出标志
        swapped = False
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        # 如果没有发生交换,说明数组已经有序,提前退出
        if not swapped:
            break
    return arr

# 示例
arr = [64, 34, 25, 12, 22, 11, 90]
sorted_arr = bubble_sort(arr)
print("Sorted array is:", sorted_arr)

2.选择排序

算法思想:

选择排序的工作原理是将未排序序列中最小(或最大)元素存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

具体实现:

def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        # 假设当前元素为最小值
        min_idx = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        # 交换找到的最小值和当前元素
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

# 示例
arr = [64, 25, 12, 22, 11]
sorted_arr = selection_sort(arr)
print("Sorted array is:", sorted_arr)

3.插入排序

算法思想:

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,找到相应位置并插入时,不需要移动元素(实际上是将大于插入元素的元素向后移动一位),只需将要插入的元素移到正确的位置即可。

具体来说,插入排序算法从数组的第二个元素开始,假设第一个元素已经被排序(即长度为1的有序序列)。然后,取出下一个元素,在已经排序的元素序列中从后向前扫描,找到相应位置并插入。重复以上步骤,直到所有元素都排序完毕。

具体实现:

def insertion_sort(arr):
    # 遍历数组,从第二个元素开始(因为第一个元素默认已排序)
    for i in range(1, len(arr)):
        key = arr[i]  # 当前需要插入的元素
        j = i - 1  # 已排序部分的最后一个元素的索引
        
        # 在已排序部分从后向前扫描,找到插入位置
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]  # 将大于key的元素向后移动一位
            j -= 1
        
        # 插入key到正确位置
        arr[j + 1] = key
    
    return arr

# 示例
arr = [12, 11, 13, 5, 6]
sorted_arr = insertion_sort(arr)
print("Sorted array is:", sorted_arr)

高级排序算法

1.归并排序

算法思想:

归并排序的核心思想是将一个大数组分成两个较小的子数组,分别进行排序,然后将排序好的两个子数组合并成一个有序的数组。这个过程可以递归地进行,直到每个子数组只包含一个元素或为空。归并排序类似于二叉树的后序遍历,会持续划分区间,直到区间内元素有序,然后利用额外空间对元素进行排序,并将它们合并回原区间,直至整个序列有序。

具体实现:

归并排序的具体实现可以分为递归和非递归两种方式。以下是递归实现的步骤:

  • 确定递归的结束条件,即当数组长度为1时,认为已经有序,直接返回。
  • 计算中间位置mid,将数组一分为二。
  • 递归地对左半部分和右半部分进行归并排序。
  • 合并两个有序的子数组,得到一个有序的数组。

非递归实现的思想与递归相似,但实现方式略有不同。它通常从单个元素的组开始,逐步扩大为2个元素、4个元素的组(二倍数扩大组数),然后依次合并这些组,直到整个数组有序。

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left_half = merge_sort(arr[:mid])
    right_half = merge_sort(arr[mid:])
    
    return merge(left_half, right_half)

def merge(left, right):
    sorted_arr = []
    i = j = 0
    
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            sorted_arr.append(left[i])
            i += 1
        else:
            sorted_arr.append(right[j])
            j += 1
    
    sorted_arr.extend(left[i:])
    sorted_arr.extend(right[j:])
    
    return sorted_arr

# 示例
arr = [38, 27, 43, 3, 9, 82, 10]
sorted_arr = merge_sort(arr)
print("Sorted array using Merge Sort:", sorted_arr)

2.快速排序

算法思想:

快速排序的核心思想是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序类似于二叉树的前序遍历,首先选择一个基准值(key),然后不断划分区间,对区间内的元素进行排序,直到整个序列有序。

具体实现:

快速排序的具体实现通常包括以下几个步骤:

  • 选择一个基准元素(pivot),可以选择数组的第一个元素、最后一个元素、中间元素或随机选择的一个元素。
  • 进行分区操作,重新排列数组,使得所有比基准元素小的元素都移动到基准的前面,所有比基准元素大的元素都移动到基准的后面(相同的数可以到任何一边)。
  • 递归地对基准左侧和右侧的子数组进行快速排序。
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    
    pivot = arr[len(arr) // 2]  # 选择中间元素作为基准
    left = [x for x in arr if x < pivot]  # 所有小于基准的元素
    middle = [x for x in arr if x == pivot]  # 所有等于基准的元素
    right = [x for x in arr if x > pivot]  # 所有大于基准的元素
    
    return quick_sort(left) + middle + quick_sort(right)

# 或者使用原地快速排序(in-place quick sort)
def quick_sort_inplace(arr, low, high):
    if low < high:
        pi = partition(arr, low, high)
        quick_sort_inplace(arr, low, pi - 1)
        quick_sort_inplace(arr, pi + 1, high)

def partition(arr, low, high):
    pivot = arr[high]  # 选择最后一个元素作为基准
    i = low - 1  # 较小元素的索引
    
    for j in range(low, high):
        if arr[j] <= pivot:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]  # 交换
    
    arr[i + 1], arr[high] = arr[high], arr[i + 1]  # 将基准元素放到正确位置
    return i + 1

# 示例(使用原地快速排序)
arr = [10, 7, 8, 9, 1, 5]
quick_sort_inplace(arr, 0, len(arr) - 1)
print("Sorted array using Quick Sort (in-place):", arr)

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

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

相关文章

《Object类》

目录 一、Object类 1.1 定义与地位 1.2 toString()方法 1.3 equals()方法 1.4 hashcode()方法 一、Object类 1.1 定义与地位 Object类是Java语言中的根类&#xff0c;所有的类&#xff08;除了Object类&#xff09;都直接或间接继承自Object。这就意味着在Java中&#xf…

Vercel 设置自动部署 GitHub 项目

Vercel 设置自动部署 GitHub 项目 问题背景 最近 Vercel 调整了其部署政策&#xff0c;免费版用户无法继续使用自动部署功能&#xff0c;除非升级到 Pro 计划。但是&#xff0c;我们可以通过配置 Deploy Hooks 来实现同样的自动部署效果。 解决方案 通过设置 Vercel 的 Dep…

2023年9月GESPC++一级真题解析

一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 题号 123456789101112131415 答案 CDBCDBACACBBDDA 1. 我们通常说的 “ 内存 ” 属于计算机中的&#xff08;&#xff09;。 A. 输出设备 B. 输 ⼊ 设备 C. 存储设备 D. 打印设备 【答案】 C 【考纲知识点】…

Laravel对接SLS日志服务

Laravel对接SLS日志服务&#xff08;写入和读取&#xff09; 1、下载阿里云的sdk #通过composer下载 composer require alibabacloud/aliyun-log-php-sdk#对应的git仓库 https://github.com/aliyun/aliyun-log-php-sdk2、创建sdk请求的service <?phpnamespace App\Ser…

SQL注入--报错注入--理论

什么是报错注入&#xff1f; 正常用户向数据库查询数据&#xff0c;查询语句出现错误时会返回报错信息。 如果数据库对查询语句的输入和数据的输出没有进行合理检测&#xff0c;攻击者就可以通过构造语句让报错信息中包含数据库的内容。 基本利用形式 updatexml注入 函数形…

ECharts柱状图-带圆角的堆积柱状图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

002 MATLAB语言基础

01 变量命名规则 变量名只能由字母、数字和下划线组成&#xff0c;且必须以字母开头&#xff1b; 变量名区分字母的大小写&#xff1b; 变量名不能超过最大长度限制&#xff1b; 关键字不能作为变量名&#xff0c;如for、end和if等&#xff1b; 注意&#xff1a;存变量命名时…

Java 对象头、Mark Word、monitor与synchronized关联关系以及synchronized锁优化

1. 对象在内存中的布局分为三块区域&#xff1a; &#xff08;1&#xff09;对象头&#xff08;Mark Word、元数据指针和数组长度&#xff09; 对象头&#xff1a;在32位虚拟机中&#xff0c;1个机器码等于4字节&#xff0c;也就是32bit&#xff0c;在64位虚拟机中&#xff0…

RTL8211F 1000M以太网PHY指示灯

在RK3562 Linux5.10 SDK里面已支持该芯片kernel-5.10/drivers/net/phy/realtek.c&#xff0c;而默认是没有去修改到LED配置的&#xff0c;我们根据硬件设计修改相应的寄存器配置&#xff0c;该PHY有3个LED引脚&#xff0c;我们LED0不使用&#xff0c;LED1接绿灯&#xff08;数据…

通过IIC访问模块寄存器[ESP--1]

上一节中&#xff0c;我们简单使用ESP函数来从主机视角扫描所有的IIC设备|上一篇文章的链接|&#xff0c;但是并不存在主从机之间的交流。这显然是不合理的&#xff0c;这个小节我们来学习如何实现主从机之间的通信 模块的寄存器 不说最简单的电阻电容电感&#xff0c;稍微复…

Spring Cloud Netflix 系列:Eureka 经典实战案例和底层原理解析

文章目录 前言Eureka 简介架构设计工作流程 项目 demo 构建Eureka Server 的搭建Eureka Client 的配置补充说明 运行效果 深入使用Eureka 注册中心添加认证搭建 Eureka 集群实现高可用双节点集群搭建 运行效果补充说明为什么要配置 不同host 原理解析服务注册、心跳续期详细流程…

数字赋能,气象引领 | 气象景观数字化服务平台重塑京城旅游生态

在数字化转型的浪潮中&#xff0c;旅游行业正以前所未有的速度重塑自身&#xff0c;人民群众对于高品质、个性化旅游服务需求的日益增长&#xff0c;迎着新时代的挑战与机遇&#xff0c;为开展北京地区特色气象景观预报&#xff0c;打造“生态气象旅游”新业态&#xff0c;助推…

(python)unittest框架

unittest unnitest介绍 TestCase测试用例 书写真正的用例脚本

Hadoop 系列 MapReduce:Map、Shuffle、Reduce

文章目录 前言MapReduce 基本流程概述MapReduce 三个核心阶段详解Map 阶段工作原理 Shuffle 阶段具体步骤分区&#xff08;Partition&#xff09;排序&#xff08;Sort&#xff09;分组&#xff08;Combine 和 Grouping&#xff09; Reduce 阶段工作原理 MapReduce 应用场景Map…

微服务即时通讯系统的实现(服务端)----(1)

目录 1. 项目介绍和服务器功能设计2. 基础工具安装3. gflags的安装与使用3.1 gflags的介绍3.2 gflags的安装3.3 gflags的认识3.4 gflags的使用 4. gtest的安装与使用4.1 gtest的介绍4.2 gtest的安装4.3 gtest的使用 5 Spdlog日志组件的安装与使用5.1 Spdlog的介绍5.2 Spdlog的安…

uniapp发布android上架应用商店权限

先看效果&#xff1a; 实现原理&#xff1a; 一、利用uni.addInterceptor的拦截器&#xff0c;在一些调用系统权限前拦截&#xff0c;进行弹窗展示&#xff0c;监听确定取消实现业务逻辑。 二、弹窗是原生nativeObj进行drawRect绘制的 三、权限申请调用使用的 plus.android.…

AmazonS3集成minio实现https访问

最近系统全面升级到https&#xff0c;之前AmazonS3大文件分片上传直接使用http://ip:9000访问minio的方式已然行不通&#xff0c;https服务器访问http资源会报Mixed Content混合内容错误。 一般有两种解决方案&#xff0c;一是升级minio服务&#xff0c;配置ssl证书&#xff0c…

【代码pycharm】动手学深度学习v2-08 线性回归 + 基础优化算法

课程链接 线性回归的从零开始实现 import random import torch from d2l import torch as d2l# 人造数据集 def synthetic_data(w,b,num_examples):Xtorch.normal(0,1,(num_examples,len(w)))ytorch.matmul(X,w)bytorch.normal(0,0.01,y.shape) # 加入噪声return X,y.reshape…

英文版本-带EXCEL函数的数据分析

一、问题&#xff1a; 二、表格内容 三、分析结果 四、具体的操作步骤&#xff1a; 销售工作表公式设计与数据验证 类别&#xff08;Category&#xff09;列公式&#xff1a; 在Category列&#xff08;假设为D列&#xff09;&#xff0c;根据ProductCode在Catalogue工作表中查找…

Ease Monitor 会把基础层,中间件层的监控数据和服务的监控数据打通,从总体的视角提供监控分析

1. 产品定位 Ease Monitor 有如下的产品定位&#xff1a; 关注于整体应用的SLA。 主要从为用户服务的 API 来监控整个系统。 关联指标聚合。 把有关联的系统及其指示聚合展示。主要是三层系统数据&#xff1a;基础层、平台中间件层和应用层。 快速故障定位。 对于现有的系统…