排序算法汇总

news/2024/11/20 13:33:29/

https://blog.csdn.net/weixin_30342639/article/details/105343780

#include
#include
#include
#include
using namespace std;

// https://blog.csdn.net/weixin_30342639/article/details/105343780

总览

1、选择排序- 不稳定!

2、冒泡排序-稳定

3、插入排序-稳定

4、快排

5、堆排

6、归并排序–稳定

(稳定的只有插入、冒泡、归并)

下面是非比较排序,稳定与否就不要记了。(好像都是稳定的)

7、希尔排序(插入排序的一种)–不稳定!
是插入排序的改进版本,基于分组的思想

8、计数排序 时间复杂度是O(n),很低,代价是空间复杂度很大,为O(n),不稳定

计数排序会创建一个临时的数组,里面存放每个数出现的次数。
计数排序仅适合数据跨度不大的场景。

9、桶排序 复杂度:桶排序执行的高效与否和是否是稳定的取决于哈希散列的算法以及内部排序的结果

桶排序类似于哈希表,通过一定的映射规则将数组中的元素映射到不同的桶中,每个桶内进行内部排序,最后将每个桶按顺序输出就行了。
桶排序执行的高效与否和是否是稳定的取决于哈希散列的算法以及内部排序的结果。
需要注意的是,这个映射算法并不是常规的映射算法,要求是每个桶中的所有数都要比前一个桶中的所有数都要大,这样最后输出的才是一个排好序的结果。
比如说第一个桶中存1-30的数字,第二个桶中存31-60的数字,第三个桶中存61-90的数字...

10、基数排序 复杂度就不要记了

不是很了解

1 选择排序----了解即可

//时间复杂度O(N2),空间复杂度O(1)
//算法:第一次遍历找到最小的,和第一个元素交换。第二次遍历找到最小的,和第二个元素交换

class Solution1
{public:void sort(vector<int>& nums){int n=nums.size();for(int i=0;i<n;i++){int minindex=i;for(int j=i;j<n;j++){if(nums[j]<nums[i])minindex=j;}swap(nums[i],nums[minindex]);}return ;}};

2–冒泡排序—了解即可–时间复杂度太高

//时间复杂度O(N2) 空间复杂度O(1)
//算法流程:从前往后遍历,两两比较。将大的放在后面。遍历完一次后,数组的最后一个元素就是最大的。遍历n次

class Solution2
{
public:void sort(vector<int> & nums){int n=nums.size();for(int i=0;i<n-1;i++){for(int j=0;j<n-i-1;j++){if(nums[j]>nums[j+1])swap(nums[j],nums[j+1]);}}return ;}
};

3-插入排序–重点

//时间复杂度O(n2),,空间复杂度O(1),并且是稳定的
//之所以必上面两种时间复杂度好,是因为,他在数组的有序的部分,不会进行多余的比较。也就是,在基本有序时,时间复杂度会接近O(N)

class Solution3
{
public:void sort(vector<int> & nums){int n=nums.size();for(int i=1;i<n;i++){for(int j=i;j>0;j--){if(nums[j]<nums[j-1])swap(nums[j],nums[j-1]);else break;}}return ;}
};

上面三种是基本的排序,后面是高阶的时间复杂度格更低的排序

4–快速排序

//1 版本1–
//每次确定一个元素的位置

class Solution3
{
public:void quicksort(vector<int> & nums){int n=nums.size();process(nums,0,n-1);return ;}//这个函数将L~R的位置的元素排好序void process(vector<int>& nums,int L,int  R ){if(L>=R) return ;int mid=partition(nums,L,R);process(nums,L,mid-1);process(nums,mid+1,R);}//这个函数以nums最右边的元素作为基准,将其放在其应该在的位置,小于等于nusm[r]的防左边int partition(vector<int> & nums,int L,int R){if(L>R){return -1;}if(L==R){return L;}int prewrite=L;int index=L;while(index<R){if(nums[index]<=nums[R]){swap(nums[index],nums[prewrite]);prewrite++;}index++;}swap(nums[prewrite],nums[R]);return prewrite;}
};

版本2–每次确定一组值相同的元素的位置:


class Solution3
{
public:void quicksort(vector<int> & nums){int n=nums.size();process(nums,0,n-1);}//这个函数将L~R的位置的元素排好序void process(vector<int>& nums,int L,int  R ){//递归的base-caseif(L>=R){return ;}vector<int> equalarea =partition(nums,L,R);process(nums,L,equalarea[0]-1);process(nums,equalarea[1]+1,R);}//这个函数以nums最右边的元素作为基准,将其放在其应该在的位置,小于等于nusm[r]的防左边//注意的是less指针和more指针的含义不再是待改写的指针,而是已经完成排序的边界,也就是完成的排序的范围是[,less]和[more,]。也就是说,待改写的区域是(less,more),而不是[less,more]vector<int> partition(vector<int> & nums,int L,int R){if(L>R)return{-1,-1};if(L==R){return{L,R};}int less=L-1;int more=R;int index=L;while(index<more){if(nums[index]==nums[R]){index++;}else if(nums[index]<nums[R]){swap(nums[++less],nums[index]);index++;}else if(nums[index]>nums[R]){swap(nums[index],nums[--more]);//index并不变化} }swap(nums[more],nums[R]);return {less+1,more};}
};

版本三:最终版本


class Solution
{public:vector<int> quicksort(vector<int>& nums){int n=nums.size();process(nums,0,n-1);return nums;}void process(vector<int>& nums,int L,int R){if(L>=R){return;}int temp=rand()%(R-L+1);swap(nums[L+temp],nums[R]);vector<int> equalarea=partition(nums,L,R);process(nums,L,equalarea[0]-1);process(nums,equalarea[1]+1,R);}vector<int> partition(vector<int>& nums,int L,int R){if(L>R)return{-1,-1};if(L==R)return {L,L};int less=L-1;int more=R;int index=L;while(index<more){if(nums[index]==nums[R])index++;else if(nums[index]<nums[R]){swap(nums[index],nums[++less]);index++;}else if(nums[index]>nums[R]){swap(nums[index],nums[--more]);}}swap(nums[more],nums[R]);return {less+1,more};}
};int main()
{vector<int> nums{1,4,3,6,5,8,9,4};Solution1 slu;slu.sort(nums);for(auto it:nums){cout<<it<<endl;}return 0;
}

5 归并排序

class Solution
{public:vector<int> sortArray(vector<int> & nums){int l=0;int r=nums.size()-1;mergesort(nums,l,r);return nums;}//将left到right变为有序的void mergesort(vector<int>&nums,int left,int right){//base_caseif(left==right)return;int mid=left+(right-left)/2;//将left到mid变为有序的mergesort(nums,left,mid);//将mid到right变为有序的mergesort(nums,mid+1,right);//merge的过程,mid两侧有序的数组合并为整个数组有序的merge(nums,left,mid,right);}void merge(vector<int> & nums,int L,int M,int R){vector<int> temp(R-L+1);int i=0;//左侧数据的起始的位置int p1=L;//右侧数据的起始的位置int p2=M+1;while(p1<=M && p2<=R){if(nums[p1]<nums[p2]){temp[i]=nums[p1];p1++;}else {temp[i]=nums[p2];p2++;}i++;}while(p1<=M){temp[i]=nums[p1];p1++;i++;}while(p2<=R){temp[i]=nums[p2];p2++;i++;}for(int i=0;i<temp.size();i++){nums[L+i]=temp[i];}}};

堆排—小根堆排序

i 结点的父结点 par = floor((i-1)/2) 「向下取整」i 结点的左子结点 2 * i +1i 结点的右子结点 2 * i + 2

//模拟priority_queue

class Heap
{
public:vector<int> vec;int capacity;int count;void swapNode(int i,int j){swap(vec[i],vec[j]);}//小根堆的上浮操作---在堆中将index节点上浮void siftup_minheap(int index){if(index==0) return;cout<<"..."<<endl;int parentNode=(index-1)/2;while(parentNode>=0){if(vec[parentNode]<vec[index])break;//父节点比这个节点小,则停止上滤swapNode(index,parentNode);index=parentNode;if(index==0) break;parentNode=(index-1)/2;}}//小根堆的下沉操作--下沉的范围是[index,n),一般是vec.size()void siftdown_minheap(int index,int n){int i=index;int j=2*i+1;//index节点的左儿子while(j<n){if(j+1<n && vec[j+1]<vec[j]) j++;//j是左儿子和右儿子。较小的那个的下标if(vec[i]<vec[j]) break;//如果 当前节点比两个孩子都要小,那么停止下沉swapNode(i,j);i=j;j=2*i+1;}}//小根堆的插入操作void insert(int num){vec.push_back(num);int index=vec.size();siftup_minheap(index-1);}//小根堆的删除堆顶元素操作--先将根节点和末尾元素互换,然后popback,然后从根节点开始下沉void del(){int n=vec.size();swapNode(0,n-1);vec.pop_back();siftdown_minheap(0,vec.size());}//原地建堆的操作--复杂度是NlogNvoid  buildHeap_1(){for(int i=0;i<vec.size();i++){siftup_minheap(i);}}
//时间复杂度是N的,建堆方法--从第一个非叶子节点,往前遍历,并进行下沉操作
//根节点是0开始编号的时候,第一个非叶子节点是最后一个节点的父节点,也就是(n-1-1)/2=(n-2)/2
    void buildHeap(){int n=vec.size();for(int i=(n-2)/2;i>=0;i--){siftdown_minheap(i,vec.size());}}int top(){int temp=vec[0];return temp;}public:Heap(vector<int>& vec_){vec=vec_;}};int main()
{vector<int> vec{9,4,7,1,5,3};Heap heap_(vec);heap_.buildHeap();while(heap_.vec.size()>0){cout<<heap_.top()<<endl;heap_.del();}return 0;}

//稳定性:只有冒泡、插入、归并,这三个是稳定性的排序算法。


http://www.ppmy.cn/news/727986.html

相关文章

findfont: Font family [‘Times New Roman‘] not found. Falling back to DejaVu Sans.字体安装

问题描述 使用python对数据进行可视化的时候&#xff0c;matplotlib绘图的时候&#xff0c;提示警告如题所示&#xff1a; UserWarning: findfont: Font family [Times New Roman] not found. Falling back to DejaVu Sans. 环境说明&#xff1a;使用的是 CentOS系统&#xf…

为什么在fonts文件夹菜单中没有“安装新字体”选项

其实&#xff0c;应该不只有「安装新字体」这个项目不见&#xff0c;开启旧文件、打印&#xff0c;以及在字体菜单上的「查看」里&#xff0c;隐藏字体变化、依相似性列出字体&#xff0c;这些都有可能会不见。 造成这种情形的原因可能有三种&#xff1a;   Fonts 数据夹的属…

QFontDatabase: Cannot find font directory .../lib/fonts

银河麒麟V10 SP1 2203&#xff0c; 飞腾CPU D2000/8. 安装完Qt 5.9.9之后&#xff0c;程序运行发现只有界面没有文字&#xff0c;提示 Cannot find font directory /home/yw/Qt5.9.9/lib/fonts. Note that Qt no longer ship fonts. 原因&#xff1a;字体缺失 解决方案&#…

findfont: Font family [‘Times New Roman‘] not found. Falling back to DejaVu Sans.

问题背景&#xff1a; 远程使用服务器绘图时&#xff0c;设置font_dict中字体格式为Times New Roman&#xff0c;如下&#xff1a; font_dictdict(fontsize16,colorblack,familyTimes New Roman,# weightlight,styleitalic,) 在绘图的过程中报出以下错误&#xff1a; fin…

Latex找不到字体:Package fontspec: The font “simsun“ cannot be found

用Latex模板编译的时候找不到字体报错&#xff1a;Package fontspec: The font "simsun" cannot be found 根据知乎上的一个评论解决了&#xff0c;注释掉模板文件.cls文件中关于newtx的内容就行&#xff0c;参考网址&#xff1a; Latex 报错&#xff1a;The font c…

findfont: Font family [‘sans-serif‘] not found解决方法

在Ubuntu系统中&#xff0c;第一次利用Python进行机器学习或数值计算&#xff0c;当需要作图且图表的图例或坐标轴含有汉子时&#xff0c;一般会给出findfont: Font family [‘sans-serif’] not found的错误&#xff0c;原因是SimHei字体缺失&#xff0c;解决的办法如下&#…

(扒站工具)如何下载网站fonts文件夹

在学习web前端时&#xff0c;学习仿别人的网站&#xff0c;但是不知道别人网站上面的字体图标文件怎么下载下来?可以看到别人的fonts文件夹&#xff0c;但是和css文件夹不一样的是fonts文件夹里面的内容是下载不下来的。 如fonts文件夹中的fontawesome-webfont.eot、fontawes…

因Spring与SpringMVC配置信息写反导致Spring无法自动托管对象实例

因Spring与SpringMVC配置信息写反导致Spring无法自动托管对象实例 异常提示 03-Jul-2023 11:25:24.491 警告 [RMI TCP Connection(3)-127.0.0.1] org.springframework.context.support.AbstractApplicationContext.refresh Exception encountered during context initializat…