算法基础之八大排序

文章目录

    • 概要
    • 1. 冒泡排序(Bubble Sort)
    • 2. 选择排序(Selection Sort)
    • 3. 插入排序(Insertion Sort)
    • 4. 希尔排序(Shell Sort)
    • 5. 归并排序(Merge Sort)
    • 6. 快速排序(Quick Sort)
    • 7. 堆排序(Heap Sort)
    • 8. 计数排序(Counting Sort)
  • 小结

概要

排序算法是编程中最基础也是最重要的算法之一。通过学习和理解不同的排序算法,我们可以在实际开发中选择合适的算法来解决问题。本文将介绍八大常用排序算法,并分别用 Python、C++ 和 Java 三种语言实现。


时间复杂度

1. 冒泡排序(Bubble Sort)

算法描述: 冒泡排序是一种简单的排序算法,通过不断交换相邻元素,使得较大的元素“浮”到数组的末尾。

时间复杂度

  • 最佳情况:O(n)
  • 平均情况:O(n²)
  • 最坏情况:O(n²)

空间复杂度: O(1)
稳定性: 稳定

实现步骤

  1. 比较相邻元素,前大则交换

  2. 对每一对相邻元素重复操作

  3. 每次遍历后范围缩小1

  4. 重复直到无交换发生

代码实现

python版本

def bubble_sort(arr):n = len(arr)for i in range(n-1):for j in range(n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr

C++版本

void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// Swap elementsint temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}

Java版本

public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// Swap elementsint temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}
}

2. 选择排序(Selection Sort)

算法描述: 选择排序通过分为有序区和无序区,逐步从无序区中找到最小元素,放到有序区的末尾。

时间复杂度:

  • 最佳情况:O(n²)
  • 平均情况:O(n²)
  • 最坏情况:O(n²)

空间复杂度: O(1)

稳定性: 不稳定

代码实现
python版本

# Python
def bubble_sort(arr):n = len(arr)for i in range(n-1):swapped = Falsefor j in range(n-1-i):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:breakreturn arr

C++版本

// C++
void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; ++i) {bool swapped = false;for (int j = 0; j < n-1-i; ++j) {if (arr[j] > arr[j+1]) {swap(arr[j], arr[j+1]);swapped = true;}}if (!swapped) break;}
}

Java版本

// Java
public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n-1; i++) {boolean swapped = false;for (int j = 0; j < n-1-i; j++) {if (arr[j] > arr[j+1]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;swapped = true;}}if (!swapped) break;}
}

3. 插入排序(Insertion Sort)

算法思想: 将未排序元素逐个插入已排序序列的合适位置

时间复杂度:

  • 平均:O(n²)

  • 最坏:O(n²)

  • 最好:O(n)

稳定性: 稳定

python版本

# Python
def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i-1while j >=0 and key < arr[j] :arr[j+1] = arr[j]j -= 1arr[j+1] = keyreturn arr

C++版本

// C++
void insertionSort(int arr[], int n) {for (int i = 1; i < n; ++i) {int key = arr[i];int j = i-1;while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}
}

Java版本

// Java
public static void insertionSort(int[] arr) {for (int i = 1; i < arr.length; ++i) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}
}

4. 希尔排序(Shell Sort)

算法思想: 改进的插入排序,通过间隔分组进行预处理
时间复杂度: O(n log n) ~ O(n²)
稳定性: 不稳定

python版本

# Python
def shell_sort(arr):n = len(arr)gap = n//2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j-gap] > temp:arr[j] = arr[j-gap]j -= gaparr[j] = tempgap //= 2return arr

C++版本

// C++
void shellSort(int arr[], int n) {for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; ++i) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)arr[j] = arr[j - gap];arr[j] = temp;}}
}

Java版本

// Java
public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)arr[j] = arr[j - gap];arr[j] = temp;}}
}

5. 归并排序(Merge Sort)

算法思想: 分治法,递归拆分后合并有序子序列
时间复杂度: O(n log n)
稳定性: 稳定

python版本

# Python
def merge_sort(arr):if len(arr) > 1:mid = len(arr)//2L = arr[:mid]R = arr[mid:]merge_sort(L)merge_sort(R)i = j = k = 0while i < len(L) and j < len(R):if L[i] < R[j]:arr[k] = L[i]i += 1else:arr[k] = R[j]j += 1k += 1while i < len(L):arr[k] = L[i]i += 1k += 1while j < len(R):arr[k] = R[j]j += 1k += 1return arr

C++版本:

// C++
void merge(int arr[], int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;int L[n1], R[n2];for (int i = 0; i < n1; i++)L[i] = arr[l + i];for (int j = 0; j < n2; j++)R[j] = arr[m + 1 + j];int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}while (i < n1) arr[k++] = L[i++];while (j < n2) arr[k++] = R[j++];
}void mergeSort(int arr[], int l, int r) {if (l < r) {int m = l + (r - l)/2;mergeSort(arr, l, m);mergeSort(arr, m+1, r);merge(arr, l, m, r);}
}

Java版本

// Java
public static void mergeSort(int[] arr, int l, int r) {if (l < r) {int m = (l + r) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);int[] L = Arrays.copyOfRange(arr, l, m + 1);int[] R = Arrays.copyOfRange(arr, m + 1, r + 1);int i = 0, j = 0, k = l;while (i < L.length && j < R.length) {if (L[i] <= R[j]) arr[k++] = L[i++];else arr[k++] = R[j++];}while (i < L.length) arr[k++] = L[i++];while (j < R.length) arr[k++] = R[j++];}
}

6. 快速排序(Quick Sort)

算法思想: 分治法,选取基准元素进行分区排序
时间复杂度:

  • 平均:O(n log n)

  • 最坏:O(n²)

稳定性: 不稳定

python版本

在这里插入代码片# Python
def quick_sort(arr):if len(arr) <= 1:return arrpivot = 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)

C++版本:

// C++
int partition(int arr[], int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;swap(arr[i], arr[j]);}}swap(arr[i+1], arr[high]);return i+1;
}void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi-1);quickSort(arr, pi+1, high);}
}

Java版本

// Java
public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi-1);quickSort(arr, pi+1, high);}
}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i+1];arr[i+1] = arr[high];arr[high] = temp;return i+1;
}

7. 堆排序(Heap Sort)

算法思想: 利用堆数据结构进行选择排序
时间复杂度: O(n log n)
稳定性: 不稳定

python版本

# Python
def heapify(arr, n, i):largest = il = 2 * i + 1r = 2 * i + 2if l < n and arr[l] > arr[largest]:largest = lif r < n and arr[r] > arr[largest]:largest = rif largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n//2-1, -1, -1):heapify(arr, n, i)for i in range(n-1, 0, -1):arr[i], arr[0] = arr[0], arr[i]heapify(arr, i, 0)return arr

C++版本:

// C++
void heapify(int arr[], int n, int i) {int largest = i;int l = 2*i + 1;int r = 2*i + 2;if (l < n && arr[l] > arr[largest])largest = l;if (r < n && arr[r] > arr[largest])largest = r;if (largest != i) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(int arr[], int n) {for (int i = n/2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n-1; i > 0; i--) {swap(arr[0], arr[i]);heapify(arr, i, 0);}
}

Java版本

// Java
public static void heapSort(int[] arr) {int n = arr.length;for (int i = n/2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n-1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}
}private static void heapify(int[] arr, int n, int i) {int largest = i;int l = 2*i + 1;int r = 2*i + 2;if (l < n && arr[l] > arr[largest]) largest = l;if (r < n && arr[r] > arr[largest]) largest = r;if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}
}

8. 计数排序(Counting Sort)

适用场景: 整数排序且值范围不大
时间复杂度: O(n + k)
稳定性: 稳定

python版本

# Python
def counting_sort(arr):max_val = max(arr)count = [0] * (max_val + 1)for num in arr:count[num] += 1idx = 0for i in range(len(count)):while count[i] > 0:arr[idx] = iidx += 1count[i] -= 1return arr

C++版本:

// C++
void countingSort(int arr[], int n) {int maxVal = *max_element(arr, arr + n);int count[maxVal + 1] = {0};for (int i = 0; i < n; i++)count[arr[i]]++;int idx = 0;for (int i = 0; i <= maxVal; i++) {while (count[i]-- > 0) {arr[idx++] = i;}}
}

Java版本

// Java
public static void countingSort(int[] arr) {int maxVal = Arrays.stream(arr).max().getAsInt();int[] count = new int[maxVal + 1];for (int num : arr) count[num]++;int idx = 0;for (int i = 0; i <= maxVal; i++) {while (count[i]-- > 0) {arr[idx++] = i;}}
}

小结

排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序O(n²)O(n²)O(1)稳定
选择排序O(n²)O(n²)O(1)不稳定
插入排序O(n²)O(n²)O(1)稳定
希尔排序O(n log n)O(n²)O(1)不稳定
归并排序O(n log n)O(n log n)O(n)稳定
快速排序O(n log n)O(n²)O(log n)不稳定
堆排序O(n log n)O(n log n)O(1)不稳定
计数排序O(n + k)O(n + k)O(k)稳定

注:k为计数排序的值域范围

应用场景建议:

  • 小规模数据:插入排序

  • 通用高效:快速排序

  • 内存敏感:堆排序

  • 稳定需求:归并排序

  • 整数排序:计数排序

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

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

相关文章

html 列动态布局

样式说明&#xff1a; /* 列动态布局&#xff0c;列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }

(python)如何看自己安装的包的版本

linux pip list | grep "numpy\|scipy\|tensorflow\|keras"windows环境下 pip list | findstr "numpy scipy tensorflow keras"输出 numpy 1.13.1 scipy 0.19.1 tensorflow-cpu 2.4.0 tensorflow-estimator 2.4.0 tensorflow-gpu 2.4.0

从O(k*n)到O(1):如何用哈希表终结多层if判断的性能困局

【前言】   本文将以哈希表重构实战为核心&#xff0c;完整展示如何将传统条件匹配逻辑(上千层if-else判断)转化为O(1)的哈希表高效实现。通过指纹验证场景的代码级解剖&#xff0c;您将深入理解&#xff1a;   1.哈希函数设计如何规避冲突陷阱   2.链式寻址法的工程实现…

离线统信系统的python第三方库批量安装流程

一、关于UOS本机 操作系统&#xff1a;UOS&#xff08;基于Debian的Linux发行版&#xff09; CPU&#xff1a;海光x86 二、具体步骤 1、在联网的电脑上用控制台的pip命令批量下载指定版本的第三方库 方法A cd <目标位置的绝对路径> pip download -d . --platform many…

第 26 场 蓝桥入门赛

3.电子舞龙【算法赛】 - 蓝桥云课 问题描述 话说这年头&#xff0c;连舞龙都得电子化&#xff01;这不&#xff0c;蓝桥村的老程序员王大爷突发奇想&#xff0c;用LED灯带和一堆传感器鼓捣出了一条“电子舞龙”&#xff0c;它能根据程序指令在村里的广场上“翩翩起舞”。 广…

0012—数组

存取一组数据&#xff0c;使用数组。 数组是一组相同类型元素的集合。 要存储1-10的数字&#xff0c;怎么存储&#xff1f; C语言中给了数组的定义&#xff1a;一组相同类型元素的集合。 创建一个空间创建一组数&#xff1a; 一、数组的定义 int arr[10] {1,2,3,4,5,6,7,8,…

详细教程 | 如何使用DolphinScheduler调度Flink实时任务

Apache DolphinScheduler 非常适用于实时数据处理场景&#xff0c;尤其是与 Apache Flink 的集成。DolphinScheduler 提供了丰富的功能&#xff0c;包括任务依赖管理、动态调度、实时监控和日志管理&#xff0c;能够有效简化 Flink 实时任务的管理和部署。通过 DolphinSchedule…

Redis Copilot:基于Redis为AI打造的副驾工具

我们最近发布了Redis Copilot&#xff0c;以帮助开发者更快地使用Redis构建应用。我们的使命是使应用程序快速运行&#xff0c;并简化构建过程。为此&#xff0c;Redis Copilot作为您的AI助手&#xff0c;能够让您更迅速地完成与Redis相关的任务。您今天就可以在Redis Insight中…

了解传输层TCP协议

目录 一、TCP协议段格式 二、TCP原理 1.确认应答 2.超时重传 3.连接管理 建立连接 断开连接 4.滑动窗口 5.流量控制 6.拥塞控制 7.延时应答 8.捎带应答 9.面向字节流 10.TCP异常情况 TCP&#xff0c;即Transmission Control Protocol&#xff0c;传输控制协议。人如…

idea 如何使用deepseek 保姆级教程

1.安装idea插件codegpt 2.注册deepseek并生成apikey deepseek 开发平台&#xff1a; DeepSeek​​​​​​​ 3.在idea进行codegpt配置 打开idea的File->Settings->Tools->CodeGPT->Providers->Custom OpenAI Chat Completions的URL填写 https://api.deepseek…

面试真题 | 超图骏科 C++

构造函数的类型及其描述 在C++中,构造函数是用于初始化对象的特殊成员函数。根据用途和参数的不同,可以将构造函数分为以下几种类型: 默认构造函数(Default Constructor) 描述:没有参数的构造函数。如果类中没有定义任何构造函数,编译器会自动生成一个默认构造函数。但…

华为OD机试E卷 --矩阵扩散--24年OD统一考试(Java JS Python C C++)

文章目录 题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码题目描述 存在一个 m n 的 二维数组 ,其成员取值范围为 0 或 1。 其中值为 1 的成员具备扩散性,每经过 1s,将上下左右值为 0 的成员同化为 1。 二维数组的成员 初始值 都为 0…

系统URL整合系列视频五(后端技术实现)

视频 系统URL整合系列视频五&#xff08;后端技术实现&#xff09; 视频介绍 &#xff08;全国&#xff09;大型分布式系统Web资源URL整合需求后端技术实现。当今社会各行各业对软件系统的web资源访问权限控制越来越严格&#xff0c;控制粒度也越来越细。安全级别提高的同时也…

二叉树理论基础详解:从零开始理解数据结构的核心

二叉树理论基础详解&#xff1a;从零开始理解数据结构的核心 在算法与数据结构的学习中&#xff0c;二叉树是一种非常基础但又极其重要的数据结构。无论是编程面试还是实际开发&#xff0c;对二叉树的 理解都是必不可少的技能。本文将从头开始&#xff0c;系统地介绍二叉树的基…

Linux之kernel(1)系统基础理论(1)

Linux之Kernel(1)系统基础理论(1) Author: Once Day Date: 2025年2月6日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: Linux内核知识_Once-Day的…

Deepseek部署的模型参数要求

DeepSeek 模型部署硬件要求 模型名称参数量显存需求&#xff08;推理&#xff09;显存需求&#xff08;微调&#xff09;CPU 配置内存要求硬盘空间适用场景DeepSeek-R1-1.5B1.5B4GB8GB最低 4 核&#xff08;推荐多核&#xff09;8GB3GB低资源设备部署&#xff0c;如树莓派、旧…

如何解决 javax.xml.crypto.dsig.TransformException: 转换异常问题?亲测有效的解决方法!

1. 问题分析 1.1 异常描述 javax.xml.crypto.dsig.TransformException 是在使用 Java XML 加密和签名 API 时&#xff0c;发生的一个常见异常。它通常出现在 XML 数字签名的转换过程中&#xff0c;可能是由于签名、加密或验证过程中发生了错误。 1.2 异常场景 该异常通常发…

【读书笔记·VLSI电路设计方法解密】问题46:什么是bug覆盖率

在IC设计项目的验证过程中&#xff0c;功能测试&#xff08;通过使用测试平台&#xff09;有助于定位设计错误或漏洞。这个验证过程有三个阶段&#xff1a;构建和启动测试平台、验证基本测试用例以及验证边界情况。 在前两个阶段&#xff0c;漏洞很容易被检测到&#xff0c;因…

【python】简单的flask做页面。一组字母组成的所有单词。这里的输入是一组字母,而输出是所有可能得字母组成的单词列表

目录结构如下&#xff1a; . ├── static │ ├── css │ │ └── styles.css │ └── js │ └── scripts.js ├── templates │ ├── base.html │ ├── case_converter.html │ ├── index.html │ └── word_finder.html ├── app.py ├── tree.py…

借助 Cursor 快速实现小程序前端开发

借助 Cursor 快速实现小程序前端开发 在当今快节奏的互联网时代&#xff0c;小程序因其便捷性、高效性以及无需下载安装的特点&#xff0c;成为众多企业和开发者关注的焦点。然而&#xff0c;小程序的开发往往需要耗费大量的时间和精力&#xff0c;尤其是在前端开发阶段。幸运…