C语言排序算法

排序的过程就是增加有序度,减少逆序度,最终达到满有序度

冒泡排序

#include <stdio.h>
#include <stdbool.h>#define N 10void swap(int arr[],int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
void bubble_sort(int arr[],int n) {//i表示冒泡的次数for(int i = 0;i < N;i++) {bool isSorted = true;for(int j = 0;j < N-i;j++) {if(arr[j] > arr[j+1]) {//不能写成 >=swap(arr,j,j+1);isSorted = false;}}if(isSorted) return ;}
}

时间复杂度
最好情况:数组有序,O(n)
比较次数:n-1
交换次数:0
最坏情况:数组逆序,O(n^2)
比较次数:(n(n-1))/2
交换次数:(n(n-1))/2
稳定性:稳定
空间复杂度:O(1),原地排序

选择排序

表现稳定的排序算法之一,因为无论什么数据进去都是O(n^2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间

#include <stdio.h>void swap(int arr[],int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}void selection_sort(int arr[],int n) {for(int i = 1;i < n;i++) {int minIndex = i-1;for(int j = 1;j < n;j++) {//更新索引if(arr[j] < arr[minIndex]) {minIndex = j;}}//交换i-1和minIndex所在位置的元素swap(arr,i-1,minIndex);}
}

时间复杂度
最好情况和最坏情况都是一样的,时间复杂度都是O(n)
比较次数:(n(n-1))/2
减缓次数:n-1
空间复杂度:O(1)
稳定性:不稳定(发生长距离交换)

插入排序

工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位ui,未最新元素提供插入空间,故名插入排序。

#include <stdio.h>
//将原数组分为两部分,第一部分是有序部分,第二部分是无序部分,每次for循环,有序部分空间+1,无序部分空间-1,然后再让新增的元素在有序序列里面寻找自己插入的位置
void insertion_sort(int arr[],int n) {// i 代表无序区的第一个元素for(int i = 1;i < n;i++) {int val = arr[i];int j = i-1;while(j >= 0 && arr[j] > val) {arr[j+1] = arr[j];j--;}arr[]j+1] = val;}
}

时间复杂度
最好情况:原数组有序,O(n)
比较次数:n-1
交换次数“:0
最坏情况:原数组逆序,O(n^2)
比较次数:(n(n-1))/2
交换次数:(n(n-1))/2
当元素基本 有序时,性能非常好
空间复杂度:O(1),原地排序
稳定性:稳定

在这里插入图片描述

希尔排序

希尔排序又叫做缩小增量排序,是插入排序的改进版本,他是唯一打破时间复杂度O(n)的排序算法
在这里插入图片描述
分组之后使用插入排序对每个分组进行排序

#include <stdio.h>void shell_sort(int arr[],int n) {int gap = n/2;while(gap != 0) {//组内插入排序for(int i = gap;i < n;i++) {int val = arr[i];int j = i - gap;while( j >= 0 && arr[j] > val) {arr[j+gap] = arr[j];j -= gap; }}// 缩小增量gap /= 2;}
}

时间复杂度:比O(n^2)小,和具体的gap序列相关
空间复杂度:O(1),原地排序
稳定性:不稳定(会发生长距离交换)

归并排序

归并排序基于分治思想,将数组拆分未元素更小的数组排序,排完序再合并小数组的结果
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>void merfe_sort(int arr[],int n) {merge_sort1(arr, 0, n - 1);
}void merge_sort1(int arr[],int left,int right) {//边界条件if(left >= right) return ;int mid = left + ((right - left) >> 1);//对左半区间排序merge_sort1(arr,left,mid);//对右半区间排序merge_sort1(arr,mid + 1,right);//合并两个区间mergr(arr, left, mid, right)
}void merge(int arr[],int left,int mid,int right) {int len = right - left + 1 ;int* temp = (int*)malloc((right - left + 1)*sizeof(int));if(temp == NULL) {printf("Error:malloc failed in merge.\n");exit(1);}int i = left,j = mid + 1, k = 0;while(i <= mid && j <= right) {if(arr[i] <= arr[j]) {//如果写成 < 就变成不稳定的了temp[k++] = arr[i++];}else {temp[k++] = arr[j++];}}while(i <= mid) {temp[k++] = arr[i++];}while(j <= right) {temp[k++] = arr[j++];}//复制数据回原数组for(int i = 0;i < len;i++) {arr[left + i] = temp[i];}//释放free(temp);
}

时间复杂度:O(n^logbn)
空间复杂度:O(n)
稳定性:稳定

快速排序

快速排序可能是引用最广泛的派苏算法,快速排序流行多的原因是因为它实现简单,适用于各种不同的输入数据且在一般应用中比其他排序算法都要快很多,快速排序也是基于分治的思想。

快速排序的步骤:
(1)选取基本值(pivot),一般选取第一个数据未基准值
(2)分区(partition),将所有比基准值小的数移动到基本值的左边,把所有比基准值大的数移动到基准值的右边
(3)对左边区间进行快速排序,对右边区间进行快速排序

在这里插入图片描述

#include <stdio.h>void quick_sort(int arr[],int n) {quick_sort1(arr, 0, n - 1);
}void quick_sort1(int arr[], int left, int right) {//边界条件if(left >= right) return ;// idx 为基准值int idx = partition(arr, left, right);quick_sort1(arr, left, idx - 1);quick_sort1(arr,idx + 1, right);
}int partition(int arr[], int left, int right) {int pivot = arr[left];int i = left, j = right;while(i < j) {while(i < j && arr[j >= pivot]) {j--;}arr[i] = arr[j];while(i < j && arr[i] <= pivot) {i++}arr[j] = arr[i];}arr[i] = pivot;return i;
}

时间复杂度
最好情况:每次分区都分成大希奥相等的两份,O(nlogn)
最坏情况:每次基准值都位于最左边或者最右边,O(n^2)
空间复杂度:O(logn),递归的深度
稳定性:不稳定
改进策略:
(1)基准值的选取:随机选择,选择多个元素的中位数作为基准值
(2)分区操作优化,
(3)选择多个基准值

堆排序

二叉堆:
(1)大顶堆,根结点的键大于左右子树所有结点的键,并且左右子树都是大顶堆;
(2)小顶堆,根结点的键小于左右子树所有结点的键,并且左右子树都是小顶堆

堆排算法步骤:
(1)构大顶堆,找到第一个非叶子结点,从后往前构建大顶堆
(2)把堆顶元素和无序区的最后一个元素交换,无序区的长度减一
(3)把无序区重新调整成大顶堆
(4)重复(2)、(3)的操作,知道无序区的长度为0

#include <stdio.h>void heap_sort(int arr[],int n){// 构建大顶堆build_heap(arr,n);// 无序区的长度int len = n;while(len > 1) {swap(arr, 0, len - 1);len--;// 把无序区重新调整成大顶堆heapify(arr, 0, len);}
}void build_heap(int arr[],int n) {for(int i = (n-2)/2;i >= 0;i--) {heapify(arr, i, n);}
}void heapify(int arr[],int i,int len) {// i 表示可能违反大顶堆规则检点的索引,len表示大顶堆包含元素的个数int leftChild = 2 * i + 1;int rightChild = 2 * i + 2;int maxIdx = i;if(leftChild < len && arr[leftChild] > arr[maxIdx]) {maxIdx = leftChid;}if(rightChild < len && arr[rightChild] > arr[maxIdx]) {maxIdx = rightChild;}if(maxIdx == i) {break;}swap(arr,i,maxIdx);i = maxIdx;
}

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

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

相关文章

HTML5+CSS3小实例:人物介绍卡片2.0

实例:人物介绍卡片2.0 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><…

迟到的总结:回望 2023 年,期盼 2024 新机会、新挑战

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、RocketMQ&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏…

定时器@Scheduled使用

四种调度方法 Scheduled 是 Spring Boot 中用于创建定时任务的注解。使用此注解可以很方便地实现定时任务的自动调度。以下是常见四种参数的作用&#xff1a; 固定延迟&#xff08;Fixed Delay&#xff09;: Scheduled(fixedDelay 1000)&#xff1a;在上一个任务完成后&#…

04-微服务-Nacos

Nacos注册中心 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 1.1.认识和安装Nacos Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在…

P4994 终于结束的起点————C

目录 终于结束的起点题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示样例 1 解释数据范围提示 解题思路Code运行结果 终于结束的起点 题目背景 终于结束的起点 终于写下句点 终于我们告别 终于我们又回到原点 …… 一个个…

WorkPlus AI助理为企业提供智能客服的机器人解决方案

在数字化时代&#xff0c;企业面临着客户服务的重要挑战。AI客服机器人成为了提升客户体验和提高工作效率的关键工具。作为一款优秀的AI助理&#xff0c;WorkPlus AI助理以其智能化的特点和卓越的功能&#xff0c;为企业提供了全新的客服机器人解决方案。 为什么选择WorkPlus A…

WinForms中的UI卡死

WinForms中的UI卡死 WinForms中的UI卡死通常是由于长时间运行的操作阻塞了UI线程所导致的。在UI线程上执行的操作&#xff0c;例如数据访问、计算、文件读写等&#xff0c;如果耗时较长&#xff0c;会使得UI界面失去响应&#xff0c;甚至出现卡死的情况。 解决方法 为了避免…

家里有必要买NAS吗?

完全没有必要&#xff0c;因为用旧电脑搭建NAS不仅价格实惠&#xff0c;而且非常简单&#xff0c;效果也完全不差买了的&#xff01; 并且......还环保 教程链接&#xff1a; 用旧电脑搭建NAS在您的家庭中&#xff0c;通过将旧 PC 转变为NAS服务器&#xff0c;您可以轻松搭建…

【Unity美术】如何用3DsMax做一个水桶模型

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

实验室管理系统建设方案(LIMS)

1.实验室管理系统 1.1.系统概述 需求描述 实验室管理系统通过先进的数据处理技术对实验室进行全面管理&#xff0c;促进实验室检测流程的信息化、规范化&#xff0c;同时强化实验室检测数据的组织、分析、查询和输出&#xff0c;并对实验过程中的质量因素进行严格控制。 1.1…

2024--Django平台开发-Django知识点(四)

1.知识回顾 创建项目&#xff1a;新项目、别人项目、新版版、老版本 项目目录&#xff08;v1.0版本&#xff09; 路由系统 常见路由编写加粗样式 /index/ 函数 /index/<str:v1> 函数 re_path(ryy/(\d{4})-(\d{2})-(\d{2})/, views.yy), re_path(ryy/(?…

dnSpy调试工具二次开发1-新增菜单

测试环境&#xff1a; window 10 visual studio 2019 版本号&#xff1a;16.11.15 .net framework 4.8 开发者工具包 下载 .NET Framework 4.8 | 免费官方下载 .net 5开发者工具包 下载 .NET 5.0 (Linux、macOS 和 Windows) 利用git拉取代码(源码地址&#xff1a;Gi…