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

堆排吧,其实就是利用一个大根堆或者是小根堆来对一组数据进行合并和动态维护其顺序。

其代码本身并没有与堆的板子有太多差别,而是完全按照加入元素弹出元素那些函数来维护的,改一改就能交啦

自己黈自己(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函数有三个参数:

(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址的下一地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。

其实还是挺简单的吧。。。。。。。

主要是排序能够练习对于数组的运用,这是培养思维和能力的好方法,至于考场上嘛,,,,,,还是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 【模板】快速排序(学完归并和堆排之后的二更)的更多相关文章

  1. Golang入门(2):一天学完GO的基本语法

    摘要 在配置好环境之后,要研究的就是这个语言的语法了.在这篇文章中,作者希望可以简单的介绍一下Golang的各种语法,并与C和Java作一些简单的对比以加深记忆.因为这篇文章只是入门Golang的第二 ...

  2. 在w3cschool学完html,css,javascript,jquery以后,还是不会做前端怎么办?

    w3cschool是一个非盈利性的在线技术学习网站,提供按W3C标准编写的基础教程.完整的看完w3cschool上面的手册,可以基本掌握编程语法.基础性的东西通常都会比较零散,因此,在学习一段时间后, ...

  3. 7天学完Java基础之0/7

    笔记-7天学完Java基础之0/7 1.常用命令提示符(cmd) 启动:Win+R,输入cmd​

  4. python 快排,堆排,归并

    #归并排序 def mergeSort(a,L,R) :     if(L>=R) :         return     mid=((L+R)>>1)     mergeSort ...

  5. 学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat

    学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat 2019-05-09   19:28:42 注:项目(MyEclipse)创建的时候选择:Web Service Pr ...

  6. 零基础学完Python的7大就业方向,哪个赚钱多?

    “ 我想学 Python,但是学完 Python 后都能干啥 ?” “ 现在学 Python,哪个方向最简单?哪个方向最吃香 ?” “ …… ” 相信不少 Python 的初学者,都会遇到上面的这些问 ...

  7. Golang入门(3):一天学完GO的进阶语法

    摘要 在上一篇文章中,我们聊了聊Golang中的一些基础的语法,如变量的定义.条件语句.循环语句等等.他们和其他语言很相似,我们只需要看一看它们之间的区别,就差不多可以掌握了,所以作者称它们为&quo ...

  8. 0基础如何更快速入门Linux系统?学完Linux有哪些就业方向?

    Linux系统是使用Linux内核及开源自由软件组成的一套操作系统,是一种类UNIX系统,其内核在1991年10月5日由林纳斯·托瓦兹首次发布. 它的主要特性:Linux文件一切皆文件.完全开源免费. ...

  9. 3分钟学完Python,直接从入门到精通

    作为帅气小编,我已经把python一些模块的甩在这儿了qwq,只要你拿到这些干货,包你玩转python,直接冲向"大佬"的段位,如果已经学了C或者C++或者说如果你需要你的一段关键 ...

随机推荐

  1. Identity4实现服务端+api资源控制+客户端请求

    准备写一些关于Identity4相关的东西,最近也比较对这方面感兴趣.所有做个开篇笔记记录一下,以便督促自己下一个技术方案方向 已经写好的入门级别Identity4的服务+api资源访问控制和简单的客 ...

  2. 我爱Java系列之《JavaEE面试宝典》---【IO流面试总结】

    1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 答案 Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 Byte是计算机操作数据的最小 ...

  3. Django学习之十: staticfile 静态文件

    目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述     ...

  4. Spring(三)使用JdbcTemplate对象完成查询

    查询银行账户的数量 1.建立一个项目导入jar包(ioc aop dao 连接池 数据库驱动 ),拷贝容器对应的配置文件到src下 2.在配置文件中开启组件扫描 3.写一个DAO接口定义一个查询方法 ...

  5. python 面试题

    1.os.path与sys.path的区别是什么? os.path 主要用于系统文件路径的操作 sys.path 主要是python解释器的系统环境参数的操作 2.re模块中match和search方 ...

  6. python turtle 书写新年快乐

    文章链接:https://mp.weixin.qq.com/s/xYSKH_KLYfooIoelJH02Cg 农历2018年的最后一篇文章,踏上回家的征途前,推荐一个Python的三方库turtle, ...

  7. (办公)mysql安装完,只能通过localhost访问,而不能通过本机ip访问.(转)

    GRANT ALL PRIVILEGES ON *.* TO '; 这里面*.*代表是所有库.所有表,root是用户名,%代表所有ip都可访问,也可指定ip访问,例如'root'@'172.17.5. ...

  8. 线上centos6出现软死锁 kernel:BUG: soft lockup

    线上centos6出现软死锁 kernel:BUG: soft lockup 今天线上一台centos6机器用xshell一直连接不上,然后在xshell上显示 Message from syslog ...

  9. MySQL下载与MySQL安装图解(MySQL5.7与MySQL8.0)

    MySQL下载与MySQL安装图解(MySQL5.7与MySQL8.0) 1.MySQL下载(MySQL8.0社区版) mysql下载方法,请根据风哥以下步骤与图示来下载mysql8.0最新社区版本: ...

  10. sql面试 查找每个班级的前5名学生(取分类数据的前几条数据)

    关键字PARTITION BY 自己看代码喽~ SELECT * FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY ClassType ORDER BY Sc ...