排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程
俗话说:天下武功无坚不破,唯快不破。对于算法当然也是要使用时间最短、占用空间最小的算法来实现了。
注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果。
总之,师傅领进门,修行在个人。奋斗把!骚年!
※冒泡排序、选择排序:(不稳定,时间复杂度 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) 原理:临近的两数 ...
随机推荐
- Asp.Net MVC 上传图片到数据库
[读书笔记]Asp.Net MVC 上传图片到数据库(会的绕行) 之前上传图片的做法都是上传到服务器上的文件夹中,再将url保存到数据库.其实在MVC中将图片上传到数据库很便捷的事情,而且不用去存 ...
- iOS基础 - 数据库-SQLite
一.iOS应用数据存取的常用方式 XML属性列表 —— PList NSKeyedArchiver 归档 Preference(偏好设置) SQLite3 Core Data(以面向对象的方式操作数据 ...
- Dynamics CRM 提示“操作无效”
今天打开一个许久没用的CRM学习环境发现出现下面的错误.顿时感觉到莫名其妙.(貌似CRM的所有错误都让人感觉到莫名其妙) 于是查看系统日志,错误如下: Current key (KeyType : C ...
- DevExpress 学习使用之 ComboBoxEdit
往 StatusBar 上添加各种部件,似乎都被包装成了 barEditItem 的方式,其 Edit 属性就是具体的部件.以 ComboBoxEdit 为例,关于 ComboBoxEdit 的一些设 ...
- 使用 NPC,NPCManager 在 XNA 中创建 NPC
使用 NPC,NPCManager 在 XNA 中创建 NPC 平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐 ...
- JAVA多线程经典问题 -- 生产者 消费者
工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...
- VC 编程ANSI环境下读写Unicode文件
没有注意到文件编码的不同会产生这么多的问题,在动手以前查询了很多资料,在本博客中收藏了不少先辈的成果,在这里一并表示致敬! 关于ANSI和Unicode编码的原理在这里也不说了,主要讲下如 ...
- 数模学习笔记(四)——AHP
1.层次分析法是对复杂.较为模糊的问题作出决策的简易方法. 2.步骤: (i)建立递阶层次结构模型:最高层(目标层),中间层(准则层),最底层(措施层) (ii)构造出各层次中的所有判断矩阵 各准则在 ...
- KnockOut文档--模板绑定
目的 模板绑定使用数据render模板,然后把渲染的结果填充到Dom树中.模板通过重复或嵌套块(通常为您的视图模型数据的函数)用一种简单,方便的方式来建立复杂的UI结构 . 有两种方式使用模板: Na ...
- 两个80c51单片机之间怎样进行串行通信
以前以为串行通信只能是单片机和PC机之间进行通信,昨天无意之中看到一个程序,是单片机和单片机之间进行通信..这小东西真是神奇啊!昨天弄了很长时间没弄出来,今天在大神的帮助下终于拨开云雾见天日了. 案例 ...