八大排序源码(含优化)

文章目录

  • 1、直接插入排序
  • 2、希尔排序
  • 3、选择排序
  • 4、冒泡排序
  • 5、堆排序
  • 6、快速排序
    • 快速排序递归实现
      • 霍尔法
      • 挖坑法
      • 前后指针法
      • 快速排序小区间优化
    • 快速排序非递归实现
  • 7、归并排序
    • 归并排序递归实现
    • 归并排序非递归
  • 8、计数排序

大家好,我是纪宁,这篇文章是关于八大排序的源代码,具体实现过程会在后续文章中介绍。

1、直接插入排序

时间复杂度O(N^2),原数据越有序,效率越高。
当原数据有序时,则时间复杂度为O(N)。原数据倒序时,时间复杂度为O(N^2)
在这里插入图片描述

void InsertSort(int* a, int n)//直接插入排序
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end+1];while (end >= 0){if (a[end] >tmp){a[end + 1] = a[end];}else{break;}end--;}a[end + 1] = tmp;}
}

2、希尔排序

时间复杂度:O(N^1.3) 空间复杂度:O(1)
希尔排序是插入排序的优化,整体思路是先预排序,使原数据更接近有序,等到gap==1时,就变成了直接插入排序。

void ShellSort(int* arr, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;//gap也可以 /=2;奇特数字必须保证gap最后的值为1for (int i = 0; i < n - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];}else{break;}end -= gap;}arr[end + gap] = tmp;}}
}

3、选择排序

时间复杂度:O(N^2) 空间复杂度:O(1)
每次选择一个最大或者最小的数,使其出现在正确的位置。
在这里插入图片描述

void SelectSort(int* a, int n)
{for (int j = 0; j < n; j++){int mini = j;int maxi= n - j-1;for (int i = j; i < n-j; i++){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[mini], &a[j]);if (maxi == j){maxi = mini;//最大值如果在 j 这个位置的话,结果这个位置被换成了min 的值}Swap(&a[maxi], &a[n-1-j]);}
}

4、冒泡排序

时间复杂度:O(N^2) 空间复杂度:O(1)
思路最简单的排序,所有程序员的白月光!
在这里插入图片描述

void BubbleSort(int* a, int n)//冒泡排序
{for (int i = 0; i < n; i++){int ret = 0;//如果一趟后ret还等于0,说明数据已经有序for (int j = 0; j < n - i - 1; j++){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);ret = 1;}}if (ret == 0)break;}
}

5、堆排序

时间复杂度:O(N*logN) 空间复杂度:O(1)
建堆的时候可以采用向上调整和向下调整建堆,而排序的时候只能使用向下调整算法。
排升序建大堆,降序建小堆。

void Adjustup(int* a, int child)//向上调整
{int parent = (child - 1) / 2;while (parent >= 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void Adjustdown(int* a, int parent, int n)//向下调整
{int child = 2 * parent + 1;while (child < n){if (child + 1 < n && a[child + 1] > a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = 2 * parent + 1;}else{break;}}
}void HeapSort(int* arr, int sz)
{//第一步,建堆向上调整建堆//for (int i = 1; i < sz; i++)//{//	Adjustup(arr, i); //}//向下调整建堆for (int i = (sz - 1) / 2; i >= 0; i--){Adjustdown(arr, i, sz - 1);}int end = sz - 1;while (end > 0){Swap(&arr[0], &arr[end]);Adjustdown(arr, 0, end);end--;}
}

6、快速排序

时间复杂度:O(N*logN) 空间复杂度:O(1)

快速排序递归实现

霍尔法

在这里插入图片描述

int QuickSortPart1(int*a,int left,int right)//霍尔版本
{int* Maxi = (&a[left], &a[right], &(a[(left + right) / 2]));//三数取中Swap(&a[left], Maxi);//换到最左边int key = a[left];int keyi = left;while (left<right){while (left<right && a[right]>=key){right--;}while (left < right && a[left] <= key){left++;}Swap(&a[left], &a[right]);}Swap(&a[keyi], &a[left]);return left;
}
void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}int keyi = QuickSortPart1(arr, begin, end);/*int keyi = QuickSortPart2(arr, begin, end);int keyi = QuickSortPart3(arr, begin, end);*/QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

挖坑法

在这里插入图片描述

int QuickSortPart2(int* arr, int left, int right)//挖坑法
{int* Maxi = (&arr[left], &arr[right], &(arr[(left + right) / 2]));Swap(&arr[left], Maxi);int holei = left;int hole = arr[left];while (left < right){while (left < right && arr[right] >= hole){right--;}arr[holei] = arr[right];holei = right;while (left < right && arr[left] <= hole){left++;}arr[holei] = arr[left];holei = left;}arr[holei] = hole;return left;
}
void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}/*int keyi = QuickSortPart1(arr, begin, end);*/int keyi = QuickSortPart2(arr, begin, end);/*int keyi = QuickSortPart3(arr, begin, end);*/QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

前后指针法

在这里插入图片描述

int QuickSortPart3(int* a, int left, int right)//快排快慢指针
{int* Maxi = (&a[left], &a[right], &(a[(left + right) / 2]));Swap(&a[left], Maxi);int keyi = left;int prev = left;int cur = left+1;while (cur <= right){if (a[cur] < a[keyi]&& ++prev!= cur){Swap(&a[prev], &a[cur]);}cur++;}Swap(&a[prev],&a[keyi]);return prev;
}void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}//*int keyi = QuickSortPart1(arr, begin, end);*///int keyi = QuickSortPart2(arr, begin, end);int keyi = QuickSortPart3(arr, begin, end);QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

快速排序小区间优化

void QuickSort1(int* a, int begin, int end)
{if (begin >= end)return;// 小区间优化,小区间不再递归分割排序,降低递归次数if ((end - begin + 1) > 10){int keyi = PartSort3(a, begin, end);// [begin, keyi-1] keyi [keyi+1, end]QuickSort1(a, begin, keyi - 1);QuickSort1(a, keyi + 1, end);}else{InsertSort(a + begin, end - begin + 1);//直接插入排序}
}

快速排序非递归实现

快排非递归要用栈来实现

void QuickSortNorn(int* a, int begin, int end)
{ST st;//创建数组栈STInit(&st);//初始化栈STPush(&st, end);//入栈STPush(&st, begin);//入栈while (!STEmpty(&st))//判空{int left = STTop(&st);//取栈顶数据STPop(&st);//出栈int right = STTop(&st);STPop(&st);int keyi = QuickSortPart1(a, left,right);if (keyi + 1 < right){STPush(&st, right);STPush(&st, keyi + 1);}if (keyi - 1 > left){STPush(&st, keyi - 1);STPush(&st, left);}}STDestroy(&st);//销毁栈
}

7、归并排序

时间复杂度:O(N*logN) 空间复杂度:O(N)

归并排序递归实现

在这里插入图片描述

void _MergeSortPart(int* a, int* tmp, int begin, int end)
{if (begin >= end)return;int midi = (begin + end) / 2;_MergeSortPart(a, tmp, begin, midi);_MergeSortPart(a, tmp, midi + 1, end);int begin1 = begin, end1 = midi;int begin2 = midi + 1, end2 = end;int index = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}memcpy(a+begin, tmp+begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSortPart(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

归并排序非递归

void _MergeSortNonr(int* a, int* tmp, int begin, int end)
{int gap = 1;while (gap <= end){for (int i = 0; i <= end; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;int index = i;if (begin2 > end){break;}if (end2 > end){end2 = end;//对范围进行修正}while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));//拷贝回原数组}gap *= 2;}}
void MergeSortNonr(int* a, int n)//归并排序非递归
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSortNonr(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

8、计数排序

时间复杂度:O(MAX(N,range)) 空间复杂度:O(range)

void CountSort(int* a, int n)//计数排序
{//先找最大值和最小值int maxi = 0, mini = 0;for (int i = 1; i < n; i++){if (a[i] > a[maxi]){maxi = i;}if (a[i] < a[mini]){mini = i;}}int max = a[maxi], min = a[mini];int range = a[maxi] - a[mini]+1;int* count = (int*)malloc(sizeof(int) * range);memset(count, 0, sizeof(int) * range);for (int j = 0; j < n; j++){count[a[j] - min]++;}int i = 0;for (int j = 0; j < n; j++){while (count[j]--){ a[i++] = j + min;}}
}

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

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

相关文章

多个线程启动 ,等待全部执行完毕再搜集数据

前几天在公司的项目上有个同事使用了多线程统计数据&#xff0c;当时出现了一个用户一直使用服务器首次登录信息作为查询信息。找了半天才发现&#xff0c;线程池资源同步了。后面手动将数据set进去的。 等待线程全部执行完毕&#xff0c;这里使用的是减法计数器&#xff0c;也…

[Machine Learning] Learning with Noisy Data

文章目录 Probabilistic Perspective of NoiseBias and VarianceRobustness among Surrogate Loss FunctionsNMF Probabilistic Perspective of Noise 假设数据来源于一个确定的函数&#xff0c;叠加了高斯噪声。我们有&#xff1a; y h ( x ) ϵ y h(x) \epsilon yh(x)ϵ…

[Realtek sdk-3.4.14b]RTL8197FH-VG 2.4G to WAN吞吐量低于60%的问题分析及解决方案

问题描述 RTL8197FH-VG 2.4G wifi to WAN吞吐量低于65%的标准,正常2T2R的wifi 300Mbps x 65% = 195Mbps,但是实际只能跑到160Mbps,这个时候CPU的idl已经为0,sirq占用率达到98%左右 网络拓扑 一台PC通过2.4G WiFi连接到RTL8197FH-VG,另外一台PC直接通过WAN口连接到RTL8197…

【pwn入门】用gdb实现第1个pwn

声明 本文是B站你想有多PWN学习的笔记&#xff0c;包含一些视频外的扩展知识。 有问题的源码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> char sh[]"/bin/sh"; int func(char *cmd){system(cmd);return 0; }int main(){char …

Spring boot接收zip包并获取其中excel文件的方法

1、问题 工作中遇到一个需求&#xff0c;接收一个zip包&#xff0c;读取其中的excel文件并处理&#xff0c;减少用户多次选择目录和文件的痛点&#xff0c;该zip包包含多级目录 2、依赖 需要用到apache的Workbook类来操作Excel&#xff0c;引入以下依赖 <dependency>&l…

C++中的四种强制类型转换符详解

前 言 C 既支持 C 风格的类型转换&#xff0c;又有自己风格的类型转换。C 风格的转换格式很简单&#xff0c;但是有不少缺点&#xff1a; 转换太过随意&#xff0c;可以在任意类型之间转换。你可以把一个指向 const 对象的指针转换成指向非 const 对象的指针&#xff0c;把一…

vue-cli搭建过程(HBuilder X搭建)

vue.js:前端主流框架&#xff08;对某一方面技术完整的封装&#xff0c;是一套完善的解决方案&#xff09; vue-cli搭建项目&#xff08;官方提供脚手架&#xff09; vue脚手架&#xff1a;是一套项目搭建的快捷方式&#xff0c;可以将项目中的依赖集成进来&#xff0c;生成统…

MongoDB快速上手

文章目录 1、mongodb相关概念1.1、业务应用场景1.2、MongoDB简介1.3、体系结构1.3.1 数据库 (databases) 管理语法1.3.2 集合 (collection) 管理语法 1.4、数据模型1.5、MongoDB的特点 2、单机部署3、基本常用命令3.1、案例需求3.2、数据库操作3.2.1 选择和创建数据库3.2.2 数据…

新一代网络框架UringNet,基于最新的异步I/O

介绍 在去年的一篇文章中&#xff0c;笔者曾经提到了最新一代的网络I/O框架UringNet。具体内容可以参考Rings’ Power,性能“世界第一”的Web I/O框架。这是基于最新Linux内核的异步I/O组件io_uring开发的网络框架。由于采用了最新的异步框架&#xff0c;因此在同等硬件配置条件…

漏洞扫描环境:win10系统用VMware Workstation打开虚拟机若干问题

win10系统用VMware Workstation打开虚拟机若干问题 一 .VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;一. VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;方法一&#xff1a;1、同时按下CTRLSHIFTESC打开任务管理器功能&#xff0c;之后依次点击-详细信息-性能后出现下列界…

【GPU常见概念】GPU常见概念及分类简述

随着大模型和人工智能的爆火&#xff0c;大家对GPU的关注持续上升&#xff0c;本文简单简述下GPU经常用的概念。 GPU&#xff08;图形处理器&#xff09;&#xff0c;又称显示核心、视觉处理器、显示芯片&#xff0c;是一种专门在个人电脑、工作站、游戏机和一些移动设备&…

k8s 拉取镜像报错 no basic auth credentials

文章目录 [toc]基于现有凭据创建 Secret通过命令行创建 Secretpod 使用指定 secret 认证私有镜像仓库 省流提醒&#xff1a; 本次解决的问题是 docker login 可以正常登录&#xff0c;docker pull 也可以正常拉取镜像&#xff0c;只是 k8s 在启动 pod 的时候&#xff0c;没有指…

【Java-LangChain:面向开发者的提示工程-3】迭代优化

第三章 迭代优化 当使用 LLM 构建应用程序时&#xff0c;实践层面上很难第一次尝试就成功获得适合最终应用的 Prompt。但这并不重要&#xff0c;只要您有一个好的迭代过程来不断改进您的 Prompt&#xff0c;那么您就能够得到一个适合任务的 Prompt。虽然相比训练机器学习模型&…

辅助驾驶功能开发-测试篇(2)-真值系统介绍

1 真值系统概述 1.1 真值评测系统核心应用 快速构建有效感知真值,快速完成感知性能评估,快速分析感知性能缺陷。 主要应用场景包括: 1. 感知算法开发验证: 在算法开发周期中,评测结果可以作为测试报告的一部分,体现算法性能的提升。 2. 遴选供应…

九、2023.10.3.Linux(end).9

文章目录 33、简述mmap的原理和使用场景&#xff1f;34、互斥量能不能在进程中使用&#xff1f;35、协程是轻量级线程&#xff0c;轻量级表现在哪里&#xff1f;36、说说常见信号有哪些&#xff0c;表示什么含义&#xff1f;37、说说线程间通信的方式有哪些&#xff1f;38、说说…

关于使用 uniapp Vue3 开发分享页面 语法糖 setup 开发获取ref踩坑

上代码 前端代码 <!-- 分享弹出 --> <uni-popup ref"share" type"share" safeArea backgroundColor"#fff"><uni-popup-share></uni-popup-share> </uni-popup>处理函数 import {onNavigationBarButtonTap} from…

点击router-link时候会发生什么?

当你点击链接或按钮时&#xff0c;将会导航到 User 组件&#xff0c;就会显示相应的用户 ID。 这里说一下执行流程&#xff0c;当点击一个 router-link 时&#xff0c;Vue Router会执行以下流程&#xff1a; 1&#xff09;点击事件触发: 当你点击 router-link 组件时&#xf…

【Java 进阶篇】JDBC查询操作详解

在数据库编程中&#xff0c;查询是一项非常常见且重要的操作。JDBC&#xff08;Java Database Connectivity&#xff09;提供了丰富的API来执行各种类型的查询操作。本篇博客将详细介绍如何使用JDBC进行查询操作&#xff0c;包括连接数据库、创建查询语句、执行查询、处理结果集…

python——Django框架

一、基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django&#xff0c;只要很少的代码&#xff0c;Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容&#xff0c;并进一步开发出全功能的 Web 服务 Django 本身基于 MVC …

AttributeError: module ‘dgl‘ has no attribute ‘batch_hetero‘

DGLWarning: From v0.5, DGLHeteroGraph is merged into DGLGraph. You can safely replace dgl.batch_hetero with dgl.batch