P1177 【模板】快速排序(学完归并和堆排之后的二更)
P1177 【模板】快速排序
不用说,连题目上都标了是一道模板,那今天就来对能用到的许多排序方式进行一个总结:
选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。(稳定不稳定最后再讲)
这是选择排序的思想:每一趟在n-i+1(i=1,2,3…,n-1)个记录中选取关键字最小的记录与第i个记录交换,并作为有序序列中的第i个记录。
例如:
待排序列: 43,65,4,23,6,98,2,65,7,79
第一趟: 2,65,4,23,6,98,43,65,7,79
第二趟: 2,4,65,23,6,98,43,65,7,79
第三趟: 2,4,6,23,65,98,43,65,7,79
第四趟: 2,4,6,7,43,65,98,65,23,79
第五趟: 2,4,6,7,23,65,98,65,43,79
第六趟: 2,4,6,7,23,43,98,65,65,79
第七趟: 2,4,6,7,23,43,65,98,65,79
第八趟: 2,4,6,7,23,43,65,65,98,79
第九趟: 2,4,6,7,23,43,65,65,79,98
贴个代码:
#include <iostream>
using namespace std;
void SelectSort(int a[], int n) //选择排序
{
int mix, temp;
for (int i = ; i < n - ; i++) //每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
{
mix = i; //假设最小元素的下标 for(int j=i+1;j<n;j++)
//将上面假设的最小元素与数组比较,交换出最小的元素的下标
if (a[j] < a[mix])
mix = j; //若数组中真的有比假设的元素还小,就交换
if (i != mix)
{
temp = a[i];
a[i] = a[mix];
a[mix] = temp;
}
}
}
int main()
{
int a[] = {, , , , , , , , , };
SelectSort(a, );
for (int i = ; i < ; i++)
cout << a[i] << " ";
cout << endl;
return ;
}
很明显,我们用到了两个嵌套的循环,所以时间复杂度就是o(n^2)的
然鹅。。。。正常人都会觉得这算法太慢了吧!!!!!!
所以我们来讲个好一点的;
冒泡排序(也是我比较喜欢的一种)
具体思路是什么呢:
冒泡排序的基本思想为:
一趟冒泡排序的过程为:首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换之,然后比较第二个记录的关键字和第三个记录的关键字,依次类推,直至第n-1个记录和第n个记录的关键字进行过比较为止;
在冒泡排序的过程中,关键字较小的记录好比肥宅快乐水(雾)的气泡逐趟向上漂浮,而关键字较大的记录好比石头往下沉,每一趟有一块“最大”的石头沉到水底。
还是上面那个数
待排序列:43, 65, 4, 23, 6, 98, 2, 65, 7, 79
第一趟: 43, 4,23,6,65,2,65,7,79,98
第二趟: 4,23,6,43,2,65,7,65,79,98
第三趟: 4,6,23,2,43,7,65,65,79,98
第四趟: 4,6,2,23,7,43,65,65,79,98
第五趟: 4,2,6,7,23,43,65,65,79,98
第六趟: 2,4,6,7,23,43,65,65,79,98
冒泡排序的时间复杂度为:O(n^2),空间复杂度为O(1)
冒泡排序是稳定的;
好吧其实这俩货时间复杂度是一样的,但是我还是喜欢用冒泡QAQ
贴一下代码吧
#include <iostream>
#include <algorithm>
using namespace std;
void bubleSort(int a[], int n) //冒泡排序
{
//运用两个for循环,每次取出一个元素跟数组的其它元素比较,将最大的元素排到最后
for (int i = ; i < n - ; i++)
{ //外循环一次,就排好一个数,并放在后面,所以比较前面n-i-1个元素即可
for (int j = ; j < n - i - ; j++)
{
if (a[j] > a[j + ])
{
swap(a[j],a[j+]);//swap其实和之前那个temp的作用是一样的,就是交换一下数字而已
}
}
}
}
int main()
{
int a[] = {, , , , , , , , , };
bubleSort(a, );
for (int i = ; i < ; i++)
cout << a[i] << " ";
cout << endl;
return ;
}
冒泡排序其实还有一个挺重要的用处,就是找一堆数里头的最大数和最小数,其实就是用的冒泡的方法
for(int i=;i<=n;i++)
{
if(a[i]>Max)
Max=a[i];
}
还有一个很重要的排序方式
快速排序
一听就很快啊有没有(雾)
快速排序的思想是找一个基准数,比基准数小的扔到左边去,大的扔到右边去(升序排列时)
听起来挺简单的吧,,,代码实现可能有一点点复杂,慢慢看
代码如下
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
int findPos(int a[], int low, int high)
{
//将小于t的元素赶到t的左边,大于t的元素赶到t的右边
int t = a[low];
while (low < high)
{
while (low < high && a[high] >= t)
high--;
a[low] = a[high];
while (low < high && a[low] <= t)
low++;
a[high] = a[low];
}
a[low] = t; //返回此时t在数组中的位置
return low;
} //在数组中找一个元素,对于大于该元素和小于该元素的两个数组进行再排序,
//再对两个数组分为4个数组,再排序,直到最后每组只剩下一个元素为止
void quickSort(int a[], int low, int high) //快速排序
{
if (low > high)
return;
int pos = findPos(a, low, high);
quickSort(a, low, pos - );
quickSort(a, pos + , high);
}
int main()
{
int, n, a[];
scanf("%d", &n);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]);
quickSort(a, , sizeof(a));
for (int i = ; i < ; i++)
cout << a[i] << " ";
cout << endl;
return ;
}
我们再来看看归并排序这个东西
归并排序(最不常用但是是实打实的快的算法)
将两个的有序数列合并成一个有序数列,我们称之为"归并"。
归并排序(Merge Sort)就是利用归并思想对数列进行排序。根据具体的实现,归并排序包括"从上往下"和"从下往上"2种方式。
基本思想:先将整个数组分成两个部分,分别将两个部分排好序,然后将两个排好序的数组O(n)合并成一个数组。
我们将问题分为两个阶段:分、治
分
对于每个长度> 1的区间,拆成两个[l, mid]区间
和[mid + 1, r]区间
直接递归下去
这样的话就可以一直递归直到只剩下一个数的时候,就分完了
治
我们认为在处理区间[l,r]时,已经有[l,mid]和[mid+1,r]内分别有序,这一次的操作就是合并两个有序序列,成为一个新的长有序序列。
用两个指针分别指向左右分别走到哪了即可
举一个例子吧,比如我们要合并这两个数组(模拟一下合并过程)
135
246
显然你肯定不能把246直接接到135后面对吧,这个时候我们建两个指针S1=1和S2=1(我的习惯是下标从1开始)
然后干这样一件事先比较a[s1]和b[s2]的大小,这里1更小一点,
所以
c[i]=b[s2]; S2++;
这里其实就是用两个指针分别从要合并的两个数组的头元素指起,如果元素被合并,那么就指针++,直到两个数组的指针都指完为止,就是这一块
算法的时间复杂度就是O(nlogN)
然后再看看堆排()
堆排吧,其实就是利用一个大根堆或者是小根堆来对一组数据进行合并和动态维护其顺序。
其代码本身并没有与堆的板子有太多差别,而是完全按照加入元素弹出元素那些函数来维护的,改一改就能交啦
自己黈自己(QWQ还是gh神仙给我纠正手写堆)
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
using namespace std;
int n, a, b, Heap[], cnt = ;
inline void add(int x)
{
Heap[++cnt] = x;
int now = cnt;
while (now!=)
{
if (Heap[now] < Heap[now >> ])
swap(Heap[now], Heap[now >> ]),now>>=;
else
break;
}
}
inline void pop()
{
printf("%d\n", Heap[]);
Heap[] = Heap[cnt--];
int root = ;
while (root << <= cnt)
{
int son;
if ((root << ) + > cnt ||
Heap[root << ] < Heap[(root << ) + ])
{
son = root << ;
}
else
son = (root << ) + ;
if (Heap[son] > Heap[root])
break;
swap(Heap[root], Heap[son]);
root = son;
}
}
int main()
{
scanf("%d", &n);
for (int i = ; i <= n; ++i)
{
scanf("%d", &b);
add(b);
}
while(n)
{
pop();
n--;
}
return ;
}
值得注意的是,如果把一整个堆按照下标顺序输出去,往往是无序的
原因是这个:
堆是一个完全二叉树,所以所谓大小关系仅仅是一个树根和他的两个智障儿子的关系,而不是说按顺序输出一定是有序数列,
堆排序能完成排序,其实是依靠每一次都弹出堆顶元素,然后进行动态维护,所以最终输出的数列是一个有序数列。
上面是堆排,下面是快排,由此可见堆排的确是很快的
最后一个(超级无敌变态的做法)
c++自带STL
其实就是sort函数
头文件是#include <algorithm>
Sort函数有三个参数:
其实还是挺简单的吧。。。。。。。
主要是排序能够练习对于数组的运用,这是培养思维和能力的好方法,至于考场上嘛,,,,,,还是sort好啊(雾
最后,我们贴一下AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
int findPos(int a[], int low, int high)
{
//将小于t的元素赶到t的左边,大于t的元素赶到t的右边
int t = a[low];
while (low < high)
{
while (low < high && a[high] >= t)
high--;
a[low] = a[high];
while (low < high && a[low] <= t)
low++;
a[high] = a[low];
}
a[low] = t; //返回此时t在数组中的位置
return low;
} //在数组中找一个元素,对于大于该元素和小于该元素的两个数组进行再排序,
//再对两个数组分为4个数组,再排序,直到最后每组只剩下一个元素为止
void quickSort(int a[], int low, int high) //快速排序
{
if (low > high)
return;
int pos = findPos(a, low, high);
quickSort(a, low, pos - );
quickSort(a, pos + , high);
}
int main()
{
int n, a[];
scanf("%d", &n);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]);
quickSort(a, , n);
for (int i = ; i <= n; i++)
cout << a[i] << " ";
cout << endl;
return ;
}
P1177 【模板】快速排序(学完归并和堆排之后的二更)的更多相关文章
- Golang入门(2):一天学完GO的基本语法
摘要 在配置好环境之后,要研究的就是这个语言的语法了.在这篇文章中,作者希望可以简单的介绍一下Golang的各种语法,并与C和Java作一些简单的对比以加深记忆.因为这篇文章只是入门Golang的第二 ...
- 在w3cschool学完html,css,javascript,jquery以后,还是不会做前端怎么办?
w3cschool是一个非盈利性的在线技术学习网站,提供按W3C标准编写的基础教程.完整的看完w3cschool上面的手册,可以基本掌握编程语法.基础性的东西通常都会比较零散,因此,在学习一段时间后, ...
- 7天学完Java基础之0/7
笔记-7天学完Java基础之0/7 1.常用命令提示符(cmd) 启动:Win+R,输入cmd
- python 快排,堆排,归并
#归并排序 def mergeSort(a,L,R) : if(L>=R) : return mid=((L+R)>>1) mergeSort ...
- 学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat
学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat 2019-05-09 19:28:42 注:项目(MyEclipse)创建的时候选择:Web Service Pr ...
- 零基础学完Python的7大就业方向,哪个赚钱多?
“ 我想学 Python,但是学完 Python 后都能干啥 ?” “ 现在学 Python,哪个方向最简单?哪个方向最吃香 ?” “ …… ” 相信不少 Python 的初学者,都会遇到上面的这些问 ...
- Golang入门(3):一天学完GO的进阶语法
摘要 在上一篇文章中,我们聊了聊Golang中的一些基础的语法,如变量的定义.条件语句.循环语句等等.他们和其他语言很相似,我们只需要看一看它们之间的区别,就差不多可以掌握了,所以作者称它们为&quo ...
- 0基础如何更快速入门Linux系统?学完Linux有哪些就业方向?
Linux系统是使用Linux内核及开源自由软件组成的一套操作系统,是一种类UNIX系统,其内核在1991年10月5日由林纳斯·托瓦兹首次发布. 它的主要特性:Linux文件一切皆文件.完全开源免费. ...
- 3分钟学完Python,直接从入门到精通
作为帅气小编,我已经把python一些模块的甩在这儿了qwq,只要你拿到这些干货,包你玩转python,直接冲向"大佬"的段位,如果已经学了C或者C++或者说如果你需要你的一段关键 ...
随机推荐
- 命令模式 Command 行为型 设计模式(十八)
命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...
- 前端入门24-响应式布局(BootStrap)
声明 本篇内容摘抄自以下两个来源: BootStrap中文网 感谢大佬们的分享. 正文-响应式布局(BootStrap) 这次想来讲讲一个前端开发框架:BootStrap BootStrap 目前已经 ...
- 微信小程序之菜鸟入门教学(二)
昨天学习了一些简单的概念,今天开始实际操作,通过搭建简单的计算器来学习小程序的架构 一.小程序框架 程序框架如上图所示.由此可见,框架的基本构成为: 1. app.js . app.wxss 2. a ...
- python docx文档转html页面
文章链接:https://mp.weixin.qq.com/s/uMb2ziRS1NJ1GXIjofeANg 说到word文档转html的,网上一搜一大把,各种在线word转html页面,使用起来也方 ...
- 三星5.0以上设备最完美激活XPOSED框架的经验
对于喜欢钻研手机的小伙伴来说,常常会接触到Xposed框架以及种类繁多功能强大的模块,对于5.0以下的系统版本,只要手机能获得Root权限,安装和激活Xposed框架是异常简易的,但随着系统版本的不断 ...
- mac git从代码仓库克隆代码,修改并上传
1:添加本地秘钥到代码仓库中 open ~/ .ssh 以github为例: mac 命令行输入open ~/ .ssh,打开id_rsa.pub文件中的内容,复制到github->settin ...
- 为了约会,PM的领导能力篇来啦!
之前我们花了很大力气阐述PM的过程能力成熟度,为的是让PM把项目管理得心应手,早点下班.可再完美的过程也要人来做啊!兄弟们要是不爽了,你还有心思约会么?那怎么才能管好组里的兄弟,让他们好好执行过程,早 ...
- 简单概括下MongoDB 4.0 新特性
(1)跨文档事务支持 (ACID) 首个支持跨文档事务的NoSQL云数据库,将文档模型的速度,灵活性和功能与ACID保证相结合.现在,使用MongoDB解决各种用例变得更加容易. (2)40%迁移速度 ...
- SQLServer修改登陆账户信息
修改登陆账户信息注意事项 如果 CHECK_POLICY设置为ON,则无法使用 HASHED参数. 如果 CHECK_POLICY更改为ON,则将出现以下行为: 用当前的密码哈希值初始化密码历史记录. ...
- WebStrom中实现Vue项目的快速启动
工具:WebStrom+vue 前提:你已经安装了node.js,vuejs,会创建vue项目等一系列的操作 发生场景:希望在WebStrom中能够快速启动vue的项目,省去npm install, ...