十一大排序算法的实现

前言

终于写完了,九大排序算法亲自打一遍,给自己加深印象,算是一种模板,留给自己以后用,也分享给大家。


U p d a t e : Update: Update: 2020.12.21

新增了几个有趣的排序算法介绍。

睡觉排序,猴子排序,量子猴排。


0.插入排序

每次对于 a [ i ] a[i] a[i]插入到正确的位置,然后从该位置开始的元素都往后移动一位。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],n;
void insert_sort(){for(int i=1;i<n;i++){int x=a[i],j=i;while(j>0&&a[j-1]>x) a[j]=a[j-1],j--;a[j]=x;}
}
int main(){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);insert_sort();for(int i=0;i<n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

1.希尔排序

希尔排序就是分组插排,利用增量 w w w,进行分组,每一组使用插排即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],n;
void shell_sort(){for(int w=n/2;w>0;w>>=1)for(int i=w;i<n;i++){int x=a[i],j=i;while(j-w>=0&&a[j-w]>x) a[j]=a[j-w],j-=w;a[j]=x;}
}
int main(){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);shell_sort();for(int i=0;i<n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

2.堆排序

先对序列建立最大堆或者最小堆,建堆是从最后一个非叶子结点开始调整,这样逆序保证了之前的都是满足堆性质的。
然后每次输出根结点,然后再调整即可。

注:从 1 1 1开始:左儿子是 2 i 2i 2i,右儿子是 2 i 2i 2i,父亲是 ⌊ i 2 ⌋ \lfloor \dfrac{i}{2}\rfloor ⌊2i​⌋。

从0开始,左儿子是 2 i + 1 2i+1 2i+1,右儿子是 2 i + 2 2i+2 2i+2,父亲是 ⌊ 2 i − 1 2 ⌋ \lfloor \dfrac{2i-1}{2} \rfloor ⌊22i−1​⌋。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],n;
void down(int x,int n){int i=x,j=i<<1;while(j<=n){if(j<n&&a[j]<a[j+1]) j++;if(a[i]<a[j]) swap(a[i],a[j]);else break;i=j,j=i<<1;}
}
void heap_sort(){for(int i=n/2;i;i--) down(i,n);for(int i=n;i>1;i--) swap(a[1],a[i]),down(1,i-1);
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);heap_sort();for(int i=1;i<=n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

3.归并排序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],b[N],n;
void merge(int l,int mid,int r){int x[N],y[N],n1=mid-l+1,n2=r-mid;for(int i=0;i<n1;i++) x[i]=a[l+i];for(int i=0;i<n2;i++) y[i]=a[mid+i+1];int i=0,j=0,k=0;while(i<n1&&j<n2){if(x[i]<y[j]) b[k++]=x[i++];else b[k++]=y[j++]; }while(i<n1) b[k++]=x[i++];while(j<n2) b[k++]=y[j++];for(int i=l;i<=r;i++) a[i]=b[i-l];
}
void merge_sort(int l,int r){if(l<r){int mid=(l+r)>>1;merge_sort(l,mid);merge_sort(mid+1,r);merge(l,mid,r);}
}
int main(){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);merge_sort(0,n-1);for(int i=0;i<n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

4.冒泡排序

每次将最大的元素或者最小的元素通过交换移动即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],n;
void bubble_sort(){for(int i=0;i<n-1;i++)for(int j=0;j<n-i-1;j++)if(a[j]>a[j+1]) swap(a[j],a[j+1]);
}
int main(){scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);bubble_sort();for(int i=0;i<n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

5.基数排序

从低位到高位排序,类似桶排序,当高位相同时,低位越大放在越后面,所以用数组存时要倒着存,即使得下一次数组 a a a满足第一关键字相同时,按照第二关键字从小到大排。

时间复杂度: O ( n d ) O(nd) O(nd)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,a[N],tmp[N];
void radix_sort(){int w[10]={};int d=1,x=10;for(int i=1;i<=n;i++) while(a[i]>=x) x*=10,d++;//求出最大位数d for(int i=0,x=1;i<d;i++,x*=10){   //一共需要排d次 mst(w,0);for(int j=1;j<=n;j++) w[(a[j]/x)%10]++;for(int j=1;j<10;j++) w[j]+=w[j-1];for(int j=n;j;j--){int p=(a[j]/x)%10;tmp[w[p]--]=a[j]; //高位相同,低位越大越靠后 }swap(tmp,a);}
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);radix_sort();for(int i=1;i<=n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

6.桶排序

将数存到有序的桶中,然后找到对应位置的数赋值即可。

时间复杂度: O ( m a x ( m x , n ) ) O(max(mx,n)) O(max(mx,n))

空间复杂度: O ( m x ) O(mx) O(mx)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,a[N],b[N],ans[N];
void bucket_sort(){int mx=0;for(int i=1;i<=n;i++) b[a[i]]++,mx=max(mx,a[i]);for(int i=1;i<=mx;i++) b[i]+=b[i-1];for(int i=n;i;i--) ans[b[a[i]]--]=a[i];
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);bucket_sort();for(int i=1;i<=n;i++) printf("%d ",ans[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

7.快速排序

每次找到一个基数,比他小的放左边,比他的放右边,然后递归。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,a[N];
void quick_sort(int l,int r){if(l<r){int i=l,j=r,x=a[l];//x是基数. while(i<j){while(i<j&&a[j]>x) j--;   //从右往左找到第一个小于等于x的 if(i<j) a[i++]=a[j];//填到左边i while(i<j&&a[i]<x) i++;//从左往右找到第一个大于等于x的 if(i<j) a[j--]=a[i];//填到右边j }a[i]=x;quick_sort(l,i-1);//递归 quick_sort(i+1,r);}
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);quick_sort(1,n);for(int i=1;i<=n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

8.选择排序

每次找到第 i i i小或第 i i i大的元素放到位置 i i i。

时间复杂度: O ( n 2 ) O(n^2) O(n2)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int n,a[N];
void select_sort(){for(int i=1;i<n;i++){int k=i;for(int j=i+1;j<=n;j++) if(a[j]<a[k]) k=j;swap(a[i],a[k]);}
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);select_sort();for(int i=1;i<=n;i++) printf("%d ",a[i]);printf("\n");return 0;
}
/*
10
9 1 3 8 4 5 2 6 10 7
*/

9.睡觉排序

算法的主要思想:利用多线程,每个数对应的线程睡眠这个数值的时间,然后丢进答案数组。

时间复杂度: O ( m a x ) O(max) O(max)

J a v a Java Java代码:

public class SleepingSort {public static void main(String[] args){int []sort={10,8,6,7,3,4,1,2,5,9,11,33,12};
SleepThread[] sleepSort=new SleepThread[sort.length];
for(int i=0;i<sort.length;i++)
{sleepSort[i]=new SleepThread(sort[i]);
}
for(int i=0;i<sleepSort.length;i++)
{sleepSort[i].start();
}
}
}
class SleepThread extends Thread{int m=0;
public SleepThread(int m){this.m=m;
}
public void run(){try {sleep(m*10+10);
} catch (InterruptedException e) {e.printStackTrace();
}
System.out.print(m+" ");
}
}

10.猴子排序

前置知识

无限猴子定理:
让一只猴子在打字机上随机地按键,当按键时间达到无穷时,几乎必然能够打出任何给定的文字,比如莎士比亚的全套著作。

算法思想:每次随机一个排列,直到有序为止。
最优时间复杂度: O ( n ) O(n) O(n),最差时间复杂度: O ( ∞ ) O(∞) O(∞)
平均复杂度: O ( n × n ! ) O(n\times n!) O(n×n!)
代码就不贴了。


延申

11.量子猴排

在洗牌时利用量子化随机排列,这样的话,我们在观测这组数之前,这组数的状态是叠加的,通过这种量子化随机排列,我们划分出来了 O ( n ! ) O(n!) O(n!)个平行宇宙,如果某个宇宙没有排序就销毁掉,最后没有被销毁的宇宙,就是一次被排好序的,时间复杂度: O ( n ) O(n) O(n)


完结散花 o( ̄▽ ̄)ブ

十一大排序算法的实现相关推荐

  1. 数组的几种排序算法的实现(1)

    数据结构中的排序算法,各有用处,比如: 1,直接插入排序,在序列基本有序的情况下,移动的次数比较少,但是比较次数是一样的 复杂度O(n*n); 2,冒泡排序,这个不用说了吧,刚学C的人都懂了 3,希尔 ...

  2. 【swjtu】数据结构实验9_多种排序算法的实现

    实验内容及要求: 输入n个整数,分别用希尔排序.快速排序.堆排序和归并排序实现由小到大排序并输出排序结果.要求n=10,15,20进行三组排序实验. 实验目的: 掌握希尔排序.快速排序.堆排序.归并排 ...

  3. Java基础学习总结(28)——Java对各种排序算法的实现

    2019独角兽企业重金招聘Python工程师标准>>> 这里总结下各种排序算法的java实现 冒泡排序 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...

  4. 排序算法的实现(C/C++实现)

    存档: 1 #include <iostream> 2 #include <stdlib.h> 3 #include <sort.h> 4 #define maxs ...

  5. C++——《数据结构与算法》实验——排序算法的实现

    问题描述 1) 动态输入一组数字序列; 2)实现直接插入排序.简单选择排序.冒泡排序.快速排序算法; 3)在主函数中,依次测试上述算法. 类型定义 #define MAX SIZE 100 typed ...

  6. Python之十大经典排序算法的实现和原理

    一.冒泡排序 冒泡排序(Bubble Sort)是一种比较简单的排序算法,它重复地走访过要排序的元素,依次比较相邻两个元素,如果它们的顺序错误就把它们调换过来,直到没有元素再需要交换,排序完成. 冒泡 ...

  7. 数据结构实验四 排序算法的实现

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼416)     2019年6月4日 学院 计算机科学与教育软件学院 年级.专业.班 姓名 学号 实验课程名称 数据结构实验 成绩 实验项 ...

  8. java 排序算法面试题_面试题: java中常见的排序算法的实现及比较

    1.冒泡排序 1.1 冒泡排序普通版 每次冒泡过程都是从数列的第一个元素开始,然后依次和剩余的元素进行比较,若小于相邻元素,则交换两者位置,同时将较大元素作为下一个比较的基准元素,继续将该元素与其相邻 ...

  9. 内部排序算法的实现(插入排序、选择排序、交换排序、归并排序、计数排序)

    目录 插入排序 直接插入排序 希尔排序 选择排序 直接选择排序 堆排序 交换排序 冒泡排序 快速排序(递归) 三数取中 快速排序(hoera版) 快速排序(挖坑版) 快速排序(前后指针版) 快速排序非 ...

最新文章

  1. *Boosting*笔记
  2. scipy 图像处理(scipy.misc、scipy.ndimage)、matplotlib 图像处理
  3. 微信官方jssdk Demo -php版
  4. 【转】数据库软考笔记(一)第一章 计算机硬件基础知识笔记总结
  5. 欧氏空间内积定义_三、n维空间简介(6)矢量平移和测地线
  6. 查看mysql状态常用命令
  7. JAVA编程规范总结
  8. 比特币挖矿初创公司Layer1 CEO换任
  9. php curlopen,php自动提交表单的方法(基于fsockopen与curl)
  10. easyui-textbox 和 easyui-validatebox 设置值和获取值
  11. 表情识别(三)--基于几何与Gabor小波的多层感知
  12. 易语言对接验证码短信接口DEMO示例
  13. BFU数据结构头歌实验:基于BF算法的病毒感染检测
  14. GD32VF103_CAN发送
  15. C++上机实验六第2题
  16. SVN服务器迁移方法(Windows环境)
  17. 跨时钟域信号如何处理(一、单bit信号)
  18. WACV2020:开源基于深度学习方法DeOccNet用来去除透视光场中的前景遮挡
  19. 智能合约—简单的公开拍卖合约
  20. Aspose.word java 实现word转pdf

热门文章

  1. 简单使用萤石云,实时直播,监控回放
  2. 将顺序表中非零元素移动到顺序表的前面
  3. 分析测试电视遥控总结
  4. Hadoop分布式集群配置
  5. Ubuntu18.04 + 树莓派4B + wifi + 换源 +ssh + 防火墙相关 + mate桌面 + + vnc + ROS Melodic
  6. 50行实现C语言FM收音机-Taskbus Stdio封装器在SDR课程中的应用
  7. Steam游戏—底特律:化身成人,回家章节中女主角上二楼打扫卫生,按L Shift开窗按不动怎么办
  8. 贸易融资名词解析:出口押汇与进口押汇
  9. 说说翻转的数据结构课
  10. Memcached应用总结