常见排序算法及其C语言实现

排序算法在计算机科学中是一个非常重要的主题。本文将详细介绍几种常见的排序算法,包括快速排序、归并排序、堆排序、冒泡排序、选择排序、插入排序、桶排序和二分查找插入排序,并提供每种算法的C语言实现代码。

1. 快速排序(Quick Sort)

概述: 快速排序是一种基于分治法的高效排序算法。它通过选择一个“枢轴”(pivot)元素,将数组分成两部分,一部分比枢轴小,另一部分比枢轴大,然后递归地对这两部分进行排序。

时间复杂度

  • 最优情况:O(nlog⁡n)O(n \log n)O(nlogn)
  • 平均情况:O(nlog⁡n)O(n \log n)O(nlogn)
  • 最坏情况:O(n2)O(n^2)O(n2)(当每次选到的枢轴都是最小或最大的元素时)

C语言实现

#include <stdio.h>void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}int partition(int arr[], int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j <= high - 1; 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);}
}int main() {int arr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);quickSort(arr, 0, n - 1);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

2. 归并排序(Merge Sort)

概述: 归并排序也是一种基于分治法的排序算法。它将数组分成两个子数组,分别排序后再合并成一个有序的数组。

时间复杂度

  • 最优情况、平均情况、最坏情况:O(nlog⁡n)O(n \log n)O(nlogn)

C语言实现

#include <stdio.h>
#include <stdlib.h>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];i++;k++;}while (j < n2) {arr[k] = R[j];j++;k++;}
}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);}
}int main() {int arr[] = {12, 11, 13, 5, 6, 7};int arr_size = sizeof(arr) / sizeof(arr[0]);mergeSort(arr, 0, arr_size - 1);printf("Sorted array: ");for (int i = 0; i < arr_size; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

3. 堆排序(Heap Sort)

概述: 堆排序利用堆这种数据结构来实现排序。堆是一种完全二叉树,分为最大堆和最小堆。最大堆的性质是每个节点的值都不小于其子节点的值。

时间复杂度

  • 最优情况、平均情况、最坏情况:O(nlog⁡n)O(n \log n)O(nlogn)

C语言实现

#include <stdio.h>void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}void heapify(int arr[], int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest])largest = left;if (right < n && arr[right] > arr[largest])largest = right;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);}
}int main() {int arr[] = {12, 11, 13, 5, 6, 7};int n = sizeof(arr) / sizeof(arr[0]);heapSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

4. 冒泡排序(Bubble Sort)

概述: 冒泡排序通过重复地遍历待排序的数组,一次比较相邻的元素并交换它们的位置,如果它们的顺序错误的话。遍历数组的工作是重复进行直到没有再需要交换,也就是说该数组已经排序完成。

时间复杂度

  • 最优情况:O(n)O(n)O(n)(当数组已经有序)
  • 平均情况:O(n2)O(n^2)O(n2)
  • 最坏情况:O(n2)O(n^2)O(n2)

C语言实现

#include <stdio.h>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]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

5. 选择排序(Selection Sort)

概述: 选择排序的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

时间复杂度

  • 最优情况、平均情况、最坏情况:O(n2)O(n^2)O(n2)

C语言实现

#include <stdio.h>void selectionSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {int min_idx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[min_idx])min_idx = j;}int temp = arr[min_idx];arr[min_idx] = arr[i];arr[i] = temp;}
}int main() {int arr[] = {64, 25, 12, 22, 11};int n = sizeof(arr) / sizeof(arr[0]);selectionSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

6. 插入排序(Insertion Sort)

概述: 插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

时间复杂度

  • 最优情况:O(n)O(n)O(n)(当数组已经有序)
  • 平均情况、最坏情况:O(n2)O(n^2)O(n2)

C语言实现

#include <stdio.h>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 = j - 1;}arr[j + 1] = key;}
}int main() {int arr[] = {12, 11, 13, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);insertionSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

7. 桶排序(Bucket Sort)

概述: 桶排序是计数排序的扩展,适用于均匀分布的数据。桶排序将元素分配到有限数量的桶中,对每个桶分别排序,然后依次合并所有桶中的元素。

时间复杂度

  • 最优情况、平均情况:O(n+k)O(n + k)O(n+k)
  • 最坏情况:O(n2)O(n^2)O(n2)(当所有元素被分配到同一个桶中)

C语言实现

#include <stdio.h>
#include <stdlib.h>// 插入排序,用于桶排序中的桶内排序
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 = j - 1;}arr[j + 1] = key;}
}void bucketSort(float arr[], int n) {// 创建 n 个桶struct Bucket {int count;float* values;};struct Bucket* buckets = malloc(n * sizeof(struct Bucket));for (int i = 0; i < n; i++) {buckets[i].count = 0;buckets[i].values = malloc(n * sizeof(float));}// 将元素分配到各个桶中for (int i = 0; i < n; i++) {int bucketIndex = n * arr[i];buckets[bucketIndex].values[buckets[bucketIndex].count++] = arr[i];}// 对每个桶中的元素进行排序for (int i = 0; i < n; i++) {insertionSort(buckets[i].values, buckets[i].count);}// 合并所有桶中的元素int index = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < buckets[i].count; j++) {arr[index++] = buckets[i].values[j];}}// 释放内存for (int i = 0; i < n; i++) {free(buckets[i].values);}free(buckets);
}int main() {float arr[] = {0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434};int n = sizeof(arr) / sizeof(arr[0]);bucketSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%f ", arr[i]);printf("\n");return 0;
}

8. 二分查找插入排序(Binary Insertion Sort)

概述: 二分查找插入排序是插入排序的优化版,它使用二分查找来找到插入位置,从而减少比较次数。

时间复杂度

  • 最优情况:O(n)O(n)O(n)
  • 平均情况、最坏情况:O(n2)O(n^2)O(n2)

C语言实现

#include <stdio.h>// 二分查找用于找到插入位置
int binarySearch(int arr[], int item, int low, int high) {if (high <= low)return (item > arr[low]) ? (low + 1) : low;int mid = (low + high) / 2;if (item == arr[mid])return mid + 1;if (item > arr[mid])return binarySearch(arr, item, mid + 1, high);return binarySearch(arr, item, low, mid - 1);
}// 二分查找插入排序
void binaryInsertionSort(int arr[], int n) {for (int i = 1; i < n; i++) {int j = i - 1;int selected = arr[i];int loc = binarySearch(arr, selected, 0, j);while (j >= loc) {arr[j + 1] = arr[j];j--;}arr[j + 1] = selected;}
}int main() {int arr[] = {37, 23, 0, 17, 12, 72, 31, 46, 100, 88, 54};int n = sizeof(arr) / sizeof(arr[0]);binaryInsertionSort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

结论

通过本文,我们介绍了多种常见的排序算法,并提供了每种算法的C语言实现。每种算法有其独特的特点和适用场景,选择合适的排序算法可以根据具体需求来决定。

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

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

相关文章

毫米波移动通信系统中的波束赋形—模数混合的波束赋形架构

模数混合的波束赋形将波束赋形分为了模拟波束赋形与数字波束赋形两部分&#xff0c;其模拟部分通过移相器实现&#xff0c;数字部分通过基带预编码实现&#xff0c;&#xff0c;其结构如图2所示。当射频链路数目NRF为1时&#xff0c;认为其是一种特殊的模数混合的波束赋形。 此…

【计算机视觉】人脸算法之图像处理基础知识【七】

直方图均衡化 直方图均衡化是一种常用的图像处理技术&#xff0c;用于改善图像的对比度&#xff0c;特别是在图像的细节被埋没在暗部或亮部区域时。通过重新分配图像的像素强度值&#xff0c;使得图像的整体对比度增强&#xff0c;从而让更多的细节变得可见。 import cv2 imp…

最小生成树模板(prim,heap-prim,kruskal)

prim 出圈法&#xff0c;时间复杂度 O ( n 2 ) O(n^2) O(n2) #include<iostream> #include<vector> using namespace std; #define MAX_N 5000 #define inf 100000000 struct edge{int v,w; }; vector<edge>e[MAX_N5]; int d[MAX_N5],vis[MAX_N5]; int n,m…

IO-Iink事件

IO-LINK事件功能 IO-Link的事件功能是其通信协议中的一项重要特性&#xff0c;主要用于传输设备的故障信息和维护信息。IO-Link支持三种数据类型&#xff1a;过程数据、参数数据和事件数据。其中&#xff0c;事件数据就是用于此目的。 当IO-Link设备&#xff08;如传感器或执…

NepnepxCATCTF Pwn-Chao

文章目录 参考类型混淆异常处理的栈回退机制虚表和类的恢复假想的程序结构逆向工程场景步骤解析 idabug检查找虚表strupsc_str()alloca异常逆向maindisplayupdatecreate 新东西exp和思路 参考 https://www.cnblogs.com/winmt/articles/17018284.html 类型混淆 关于C中由虚函…

Java中如何解决BadPaddingException异常?

Java中如何解决BadPaddingException异常&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java编程中&#xff0c;BadPaddingException异常是一个…

HarmonyOS Next开发学习手册——应用启动框架AppStartup

概述 AppStartup提供了一种简单高效的初始化组件的方式&#xff0c;开发者可以使用AppStartup来显示的设置组件的初始化顺序以及之间的依赖关系&#xff0c;支持异步初始化组件加速应用的启动时间。开发者需要分别为待初始化的组件实现AppStartup提供的 StartupTask 接口&…

DoubleSummaryStatistics 及其相关类之-简介

1. DoubleSummaryStatistics 使用简介 在Java 8中&#xff0c;DoubleSummaryStatistics 类被引入作为 java.util 包的一部分。它是一个用于收集统计数据&#xff08;如计数、最小值、最大值、和、平均值等&#xff09;的类&#xff0c;特别适用于处理 double 类型的数据。 Do…

【OpenGauss源码学习 —— (ALTER TABLE(修改表空间))】

ALTER TABLE&#xff08;列存删除列&#xff09; ALTER TABLE ... SET TABLESPACEExecChangeTableSpaceForRowTable 函数ATExecSetTableSpace 函数 ExecChangeTableSpaceForRowPartition 函数ATExecSetTableSpaceForPartitionP3 函数 ExecChangeTableSpaceForCStoreTable 函数C…

DeepSeek-Coder-v2击败GPT-4 Turbo,成为竞技场最强开源编码模型!

目录 01 编码与数学击败GPT-4 Turbo 02 深度求索&#xff1a;价格战的导火索 就在刚刚&#xff0c;竞技场排名再次刷新&#xff1a;深度求索的DeepSeek-Coder-v2成为竞技场最强开源编码模型&#xff01; 它在Coding Arena中已攀升至第4名&#xff0c;水平接近GPT-4 Turbo。 没…

mysql的information_schema浅析

information_schema 是 MySQL 中的一个虚拟数据库&#xff0c;它包含了关于 MySQL 服务器的所有元数据。 information_schema 作用 元数据管理&#xff1a;提供关于数据库、表、列、索引、权限等的信息。 性能优化&#xff1a;帮助了解数据库结构和索引使用情况&#xff0c;便…

Latex学习之“usefont”用法

Latex学习之“\usefont”用法 一、通俗的解释 \usefont 是 LaTeX 中的一个命令&#xff0c;用于在文档中临时改变字体&#xff0c;其基本语法如下&#xff1a; \usefont{字体编码}{字体族}{字体系列}{字体形状}这样看起来好像蛮抽象&#xff0c;你可能以及晕了&#xff0c;什…

QT中eventFilter的用途详解

QEventFilter 是 Qt 框架中的一个机制&#xff0c;用于拦截和处理事件。这在 Qt 的事件驱动模型中非常重要&#xff0c;因为它允许我们在事件到达目标对象之前捕获并处理它们。下面是对 QEventFilter 的详细解释&#xff0c;分为几个关键部分&#xff1a; 1. 事件处理机制 在…

Arduino称重传感器和 HX711 放大器(数字秤)

Arduino称重传感器和 HX711 放大器&#xff08;数字秤&#xff09; Arduino with Load Cell and HX711 Amplifier (Digital Scale) In this guide, you’ll learn how to create a digital scale with the Arduino using a load cell and the HX711 amplifier. First, you’l…

队列。。。

目的&#xff1a; 1&#xff0e;掌握队列存储结构的表示和实现方法。 2&#xff0e;掌握队列的入队和出队等基本操作的算法实现。 3&#xff0e;了解队列在解决实际问题中的简单应用。 要求&#xff1a; &#xff08;1&#xff09;根据输入的队列长度n和各元素值建立一个循环队…

Redis-使用 jedis 操作数据

文章目录 1、Jedis简介2、环境准备3、创建maven普通项目,导入如下依赖4、测试JAVA程序和Redis之间的通信 1、Jedis简介 "Jedis" 通常是作为 "Java Redis" 的缩写或简称来理解的。Java Embedded Data Structures Interface 表示 Java嵌入式数据结构接口 2、…

高德行政区查询-综合省市县三级选择跳转

一、需求&#xff1a; 需要使用高德地图进行省市县的一个选择&#xff0c;每选择一次就在地图上对选择的省市县进行定位并画出该区域的范围。 最终效果&#xff1a; 二、准备工作 高德的API的key&#xff1a;两种 三、完整页面代码 综合的是这两篇中的内容&#xff08;不…

19、删除链表的倒数第

1、题目描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 …

Vue3从入门到精通

文章目录 前言为什么选择Vue框架Vue是什么?为什么要学习Vue? Vue简介Vue API风格选项式API(Options API)组合式API(Composition API) Vue开发前的准备创建Vue项目 Vue项目目录结构![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0400cdd482704d4d9ffa8a3a6687b12…

什么是档案业务建设评价

档案业务建设评价是对档案管理机构或部门在档案业务建设方面进行的评估和考核。评价主要根据一定的评价标准和指标&#xff0c;对档案业务的各个方面进行综合评估&#xff0c;包括档案收集、整理、保管、利用等环节&#xff0c;以及档案管理机构的组织管理、技术能力等方面。 评…