排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程
俗话说:天下武功无坚不破,唯快不破。对于算法当然也是要使用时间最短、占用空间最小的算法来实现了。
注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果。
总之,师傅领进门,修行在个人。奋斗把!骚年!
※冒泡排序、选择排序:(不稳定,时间复杂度 O(n^2))
#include "cstdio"
#include "iostream"
using namespace std; void bubble_sort (int *a, int n) {
int t;
for (int i = ; i < n - ; ++i) {
for (int j = ; j < n - i - ; ++j) {
if (a[j] > a[j + ]) {
t = a[j];
a[j] = a[j + ];
a[j + ] = t;
}
}
}
} int main () {
int n, a[];
cin >> n;
for (int i = ; i < n; ++i)
cin >> a[i];
bubble_sort (a, n);
for (int i = ; i < n; ++i)
cout << a[i] << " ";
cout << endl;
return ;
}
bubble sort
#include "cstdio"
#include "iostream"
using namespace std; void selection_sort (int *a, int n) {
int t;
for (int i = ; i < n; ++i) {
for (int j = i; j < n; ++j) {
if (a[i] > a[j]) {
t = a[j];
a[j] = a[i];
a[i] = t;
}
}
}
} int main () {
int n, a[];
cin >> n;
for (int i = ; i < n; ++i)
cin >> a[i];
selection_sort (a, n);
for (int i = ; i < n; ++i)
cout << a[i] << " ";
cout << endl;
return ;
}
selection sort
如果说冒泡和选择排序都没有弄明白的话,那你对于排序可以只记个C++STL中的sort函数和头文件就行了。
#include <algorithm>
sort (要排序数组的首地址, 要排序一共的个数);
// 默认是升序,如果想要降序的话,写一个compare函数 bool compare(int a, int b) { return a > b;}
// a < b;升序 a > b;降序
#include <iostream>
#include <algorithm>
using namespace std; int cmp(int a, int b) {
return a > b;
} int main () {
int a[] = {, , , , };
// sort (a, a+5, [](int a, int b){return a > b;});
// 这是闭包的格式, 适合函数体较短的时候使用。 sort (a, a+, cmp); for (int i = ; i < ; ++i) {
cout << a[i] << " ";
}
cout << endl;
return ;
}
C++ STL sort
sort排结构体(可以使用pair更方便)
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std; struct node {
int x, y;
}t[]; bool cmp (const node a, const node b) {
if (a.x > b.x) {
return ;
} else if (a.x==b.x && a.y<b.y) {
return ;
} else {
return ;
}
} int main () {
t[].x = ;
t[].y = ; t[].x = ;
t[].y = ; t[].x = ;
t[].y = ; t[].x = ;
t[].y = ; t[].x = ;
t[].y = ; t[].x = ;
t[].y = ; sort (t, t+, cmp);
for (int i = ; i < ; ++i) {
cout << t[i].x << ' ' << t[i].y << endl;
}
return ;
} /*
3 2
2 3
1 1
1 2
1 3
2 1
*/
sort排结构体数组
※基础快排1----选择左右两边为基准排序:(不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2))
#include <bits/stdc++.h>//万能头文件
using namespace std; void quick_sort (int a[], int l, int r) {
if (l >= r) return ;
int i = l, j = r;
int key = a[l];
while (i < j) { ///这里不能带等号,,死循环
while (i < j && a[j] >= key) {//<=是找有相同数字的时候
j --; //选的左边作为key,所以就从右边开始.
}
a[i] = a[j]; //找到一个该交换的时候退出交换。
while (i < j && a[i] <= key) { //<=是找有相同数字的时候
i ++;
}
a[j] = a[i]; //同上
}
a[i] = key;
quick_sort (a, l, i - );////应该可以交换位置,因为这两个是等效的,
quick_sort (a, i + , r);////就是排序上次key两的的值
} int main () {
int n;
int a[];
scanf ("%d", &n);
for (int i = ; i < n; ++i)
{
scanf ("%d", &a[i]);
}
quick_sort (a, , n - );
for (int i = ; i < n; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
return ;
}
Quick_sort_by_left
#include <bits/stdc++.h>
using namespace std; void quick_sort (int a[], int l, int r) {
if (l >= r) return ;
int i = l, j = r;
int key = a[r];
while (i < j) { ///这里不能带等号,,死循环
while (i < j && a[i] <= key) {//<=是找有相同数字的时候
i ++; //选的右边作为key,所以就从左边开始.
}
a[j] = a[i]; //找到一个该交换的时候退出交换。
while (i < j && a[j] >= key) { //<=是找有相同数字的时候
j --;
}
a[i] = a[j]; //同上
}
a[j] = key;//-----先替换的a[j],所以在这里补上.
quick_sort (a, l, i - );////可以交换位置,是等效的
quick_sort (a, i + , r);////就是排序上次key两的的值
} int main () {
int n;
int a[];
scanf ("%d", &n);
for (int i = ; i < n; ++i)
{
scanf ("%d", &a[i]);
}
quick_sort (a, , n - );
for (int i = ; i < n; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
return ;
}
Quick_sort_by_right
注意:快排函数最后递归的时候可以按j也可以按i,因为最后满足 i == j; 理解代码里面等号的取舍!
※基础快排2----选择任意数字为基准排序:(不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2))
#include <cstdio>
#include <iostream>
using namespace std; void quick_sort (int *a, int l, int r) {
int i = l, j = r, key = a[l + (r - l) / ];
//int key = a[r];
//从数列里面任意找一个key就行
int t;
while (i < j) {
while (i < r && a[i] < key) i ++;
//不能写成a[i] <= key,会跳过一些数字,导致不能排序
while (j > l && a[j] > key) j --;
//这两个while可以交换位置,以左右为基准的快排不能交换
if (i <= j) {
t = a[i];
a[i] = a[j];
a[j] = t; i ++;
j --;
}
}
if (i < r) quick_sort (a, i, r);
if (j > l) quick_sort (a, l, j);
} int main () {
int n;
int a[];
cin >> n;
for (int i = ; i < n; ++i)
cin >> a[i];
quick_sort (a, , n - );
for (int i = ; i < n; ++i)
cout << a[i] << " ";
cout << endl;
return ;
} Quick_sort_anyone
Quick_sort_by_anyone
简述:快速排序是对冒泡排序的一种本质改进。它的基本思想是通过一趟扫描后,使得排序序列的长度能大幅度地减少。在冒泡排序中,一次扫描只能确保最大数值的数移到正确位置,而待排序序列的长度可能只减少1。快速排序通过一趟扫描,就能确保某个数(以它为基准点吧)的左边各数都比它小,右边各数都比它大。然后又用同样的方法处理它左右两边的数,直到基准点的左右只有一个元素为止。
***另外一种快排的写法(从蓝桥杯上学习到的,思想都是一样的,只是实现有点不一样)
#include <stdio.h> void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
} int partition(int a[], int p, int r)
{
int i = p;
int j = r + ;
int x = a[p];
while(){
while(i<r && a[++i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
swap(a, p, j);
return j;
} void quicksort(int a[], int p, int r)
{
if(p<r){
int q = partition(a,p,r);
quicksort(a,p,q-);
quicksort(a,q+,r);
}
} int main()
{
int i;
int a[] = {,,,,,,,,,,,};
int N = ; quicksort(a, , N-); for(i=; i<N; i++) printf("%d ", a[i]);
printf("\n"); return ;
}
蓝桥杯
※基础快排3----调用stdlib.h中的qsort函数。
语法:
#include <stdlib.h>
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );
buf: 要排序片段的首地址。
num: 要排序片段的个数。
size:要排序元素占的字节,可以使用sizeof来求。
compare:如果函数compare 的第一个参数小于第二个参数,返回负值(升序);如果等于返回零值(不变);如果大于返回正值(降序)(函数参数必须为const void *类型)。
#include <stdio.h>
#include <stdlib.h> int cmp(const void *a, const void *b) {
return *(char*)a - *(char*)b;
// 如果数组是int类型的话,这里的char就是用int
// 下面对应sizeof(int).
} int main() {
char b[] = {""};
qsort(b, , sizeof(char), cmp);
printf("%c", b[]);
for(int i = ; i < ; i++)
printf(" %c", b[i]);
printf("\n");
return ;
}
Qsort
※归并排序:(稳定,时间复杂度 O(nlog n))
#include <stdio.h>//归并排序
#include <stdlib.h>
void merge(int a[],int b[], int f, int mid, int e)
{//合并两个数组
int i = f, j = mid + , k = f;
while(i <= mid && j <= e)//注意衔接
{
if(a[i] >= a[j]) //谁大就不把谁装到前面
b[k++] = a[j++];
else
b[k++] = a[i++];
}
while(i <= mid)//前半个有剩余
b[k++] = a[i++];
while(j <= e)//后半个有剩余
b[k++] = a[j++];
for(i = f; i <= e; i++) //最后再还给a
a[i] = b[i];
}
void mergesort(int a[], int b[], int f, int e)//内部使用递归
{
if(f < e)
{
int mid = (e + f) / ;
mergesort(a, b, f, mid); //拆分到很小很小
mergesort(a, b, mid + , e);
merge(a, b, f, mid, e);
}
}
int main(){
int n;
int a[];
int i, b[];
scanf ("%d", &n);
for (int i = ; i < n; ++i)
scanf ("%d", &a[i]);
mergesort(a, b, , n - );
for(i = ; i < n; i++)
printf("%d ", a[i]);
printf("\n");
return ;
}
Order_by_merging
简述:将数组拆分为两组,对于一个数组来说,两个数组要好排的多...依次类推,当分到只要一个元素的时候,我们就认为是有序的,然后再挨个合并相邻的数组。我们可以先递归分解,然后再归并排序。
※插入排序:
/*
* > File Name: test.cpp
* > Author: Ddlm2wxm
* > Mail: Ddlm2wxm@163.com
* > Created Time: 2016年10月20日 星期四 07时35分53秒
*********************************************************/ #include <iostream>
#include <cstdio>
using namespace std; void Insert_sort (int a[], int n) {
int i, j;
for (i = ; i < n; ++i) {
int t = a[i];
for (j = i-; j >= &&t<a[j]; --j)
a[j+] = a[j];
a[j+] = t;
}
} int main() {
int n;
int a[];
cin >> n;
for (int i = ;i < n; ++i) {
cin >> a[i];
}
Insert_sort (a, n);
for (int i =;i < n; ++i) {
cout << a[i] << " ";
}
cout << endl;
return ;
}
Insert_sort
简述:个人认为插入排序是最简单的,就是从第一个开始,认为第一个数是有序的,然后依次取后面的数字,通过遍历前面的排序好了的数组寻找取到元素的位置。
欢迎码友评论,一起成长。
排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程的更多相关文章
- Java 排序(快排,归并)
Java 排序有Java.util.Arrays的sort方法,具体查看JDK API(一般都是用快排实现的,有的是用归并) package yxy; import java.util.Arrays; ...
- 普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys
很多时候排序是为了对数据进行归类,这种排序重复值特别多 通过年龄统计人口 删除邮件列表里的重复邮件 通过大学对求职者进行排序 若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路 ...
- 【js基础】js排序方法——快排+堆排+插排+选择排
快排 Array.prototype.fastSort = function(){ var arr = this; function sort(left, right, arr){ if( left ...
- c语言中使用自带的qsort(结构体排序)+ 快排
c中没有自带的sort函数emm 不过有自带的qsort函数 (其实用法都差不多(只是我经常以为c中有sort 头文件要用 #include <stdlib.h> 一定要重新把指针指向的值 ...
- 排序之快排(JS)
快速排序(Quicksort)是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...
- 排序--QuickSort 快排
Quick の implementation 快排,就像它的名字一定,风一样的快.基本上算是最快的排序算法了.快排的基本思想是选择一个切分的元素.把这个元素排序了.所有这个元素左边的元素都小于这个元素 ...
- 使用Python完成排序(快排法、归并法)
class Sort(object): def quick_sort(self, ls): self.quick_sort_helper(ls, 0, len(ls) - 1) return ls d ...
- Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等
本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...
- 冒泡,快排算法之javascript初体验
引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排.不用数组原生的 sort() 方法来实现冒泡和快排. Part 1:冒泡排序(Bubble Sort) 原理:临近的两数 ...
随机推荐
- iOS基础 - UIDynamic
一.UIKit动力学 UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit 注意:UIKit动力学的引入,并不是 ...
- Binder机制,从Java到C (1. IPC in Application Remote Service)
转载请标注:张小燕:http://www.cnblogs.com/zhangxinyan 1. Application 中的 service 我们知道Android中Service有三种类型:Loca ...
- DateTime 格式化
在格式化的时候,希望输出2013/10/01 但可能实际的输出是2013-10-01. string s1 = result.Item1.ToString("yyyy/MM/dd" ...
- .net下将富文本编辑器文本原样读入word文档
关键词:富文本编辑器 生成word 样式 为了解决标题中提出的问题,首选需要了解,在.net环境下读取数据库中的内容动态生成word至少有2种方式,[方式一]一种方式是在项目中添加引用,例如在“添 ...
- springMVC3学习(十一)--文件上传CommonsMultipartFile
使用springMVC提供的CommonsMultipartFile类进行读取文件 需要用到上传文件的两个jar包 commons-logging.jar.commons-io-xxx.jar 1.在 ...
- 一.redis 环境搭建
1.简介 redis是一个开源的key-value数据库.它又经常被认为是一个数据结构服务器.因为它的value不仅包括基本的string类型还有 list,set ,sorted set ...
- C++11改进我们的程序之简化我们的程序1
C++11改进我们的程序之简化我们的程序(一) C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返 ...
- ASP.NET MVC学习笔记-----Filter2
ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...
- MySQL能够承受上亿万条的数据量的架构
MySQL能够承受上亿万条的数据量的架构 最近做的搜索引擎的数据量是越来越大估计了下在中国可能涉及到的1Kw的数据量,就全球来说也就是1K亿而已,最初是用的数据库是MySQL现在来说要做些优化,最终使 ...
- Twitter Storm:单机环境的安装与配置
Twitter Storm:单机环境的安装与配置 好久没写博客了,这一段时间一直被导师push着做毕业设计.由于目前的方向偏向于图像识别检索,毕设打算做一个基于分布式计算平台的图像检索系统,查阅相关资 ...