排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程

时间:2023-01-27 19:56:35

  俗话说:天下武功无坚不破,唯快不破。对于算法当然也是要使用时间最短、占用空间最小的算法来实现了。

  注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果。

 总之,师傅领进门,修行在个人。奋斗把!骚年!

※冒泡排序、选择排序:(不稳定,时间复杂度 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

简述:个人认为插入排序是最简单的,就是从第一个开始,认为第一个数是有序的,然后依次取后面的数字,通过遍历前面的排序好了的数组寻找取到元素的位置。

 欢迎码友评论,一起成长。

排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程的更多相关文章

  1. Java 排序(快排,归并)

    Java 排序有Java.util.Arrays的sort方法,具体查看JDK API(一般都是用快排实现的,有的是用归并) package yxy; import java.util.Arrays; ...

  2. 普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys

    很多时候排序是为了对数据进行归类,这种排序重复值特别多 通过年龄统计人口 删除邮件列表里的重复邮件 通过大学对求职者进行排序 若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路 ...

  3. 【js基础】js排序方法——快排&plus;堆排&plus;插排&plus;选择排

    快排 Array.prototype.fastSort = function(){ var arr = this; function sort(left, right, arr){ if( left ...

  4. c语言中使用自带的qsort(结构体排序)&plus; 快排

    c中没有自带的sort函数emm 不过有自带的qsort函数 (其实用法都差不多(只是我经常以为c中有sort 头文件要用 #include <stdlib.h> 一定要重新把指针指向的值 ...

  5. 排序之快排(JS)

    快速排序(Quicksort)是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...

  6. 排序--QuickSort 快排

    Quick の implementation 快排,就像它的名字一定,风一样的快.基本上算是最快的排序算法了.快排的基本思想是选择一个切分的元素.把这个元素排序了.所有这个元素左边的元素都小于这个元素 ...

  7. 使用Python完成排序(快排法、归并法)

    class Sort(object): def quick_sort(self, ls): self.quick_sort_helper(ls, 0, len(ls) - 1) return ls d ...

  8. Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

  9. 冒泡,快排算法之javascript初体验

    引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排.不用数组原生的 sort() 方法来实现冒泡和快排. Part 1:冒泡排序(Bubble Sort) 原理:临近的两数 ...

随机推荐

  1. node&period;js在linux下的安装

    简单说就是解压后,在bin文件夹中已经存在node以及npm,如果你进入到对应文件的中执行命令行一点问题都没有,不过不是全局的,所以将这个设置为全局就好了. ? 1 2 3 cd node-v0.10 ...

  2. servers中添加server时,看不到运行环境的选择。

    servers中添加server时,看不到运行环境的选择. 主要原因是tomcat目录中的配置文件格式不对.

  3. 使用Qt 开发图形界面的软件

    3DSlicer, a free open source software for visualization and medical image computing AcetoneISO:镜像文件挂 ...

  4. 为什么虚拟机上刚装的centos7只有lo回环网络接口?

    centos7默认安装时需要手动激活有线网卡.如果安装时没有激活,需要手动编辑vi /etc/sysconfig/network-scripts/下ifcfg-enoxxONBOOT="ye ...

  5. APK的反编译

    有秘密的地方就有见不得光的东西,我讨厌这些,所以对于某一个XX圈APP极其反感,感觉就像一个色情网站 一.ApkTool的使用 看了几个教程,自己下载的好像总是不完整,下载包解压后一个没有aapt.e ...

  6. git cherry-pick 的使用

    之前和同事在不同的分支开发一个功能的不同模块,在自己分支有用到同事分支的一些实现,被老大告诉用git cherry-pick来搞定! git cherry-pick  能够把另一个分支的一个或多个提交 ...

  7. python中&commat;classmethod &commat;staticmethod区别&lpar;转&rpar;

    pthon中3种方式定义类方法, 常规方式, @classmethod修饰方式, @staticmethod修饰方式. class A(object): def foo(self, x): print ...

  8. 四张图带你了解Tomcat系统架构

    一.Tomcat顶层架构 先上一张Tomcat的顶层结构图(图A),如下: Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service ...

  9. mysql 常用的几个函数

    IF 函数 语法:`IF`(expr1,expr2,expr3); 当expr1为ture时,值为expr2,当expr1为false时,值为expr3. 如: IFNULL 函数 语法:IFNULL ...

  10. 白盒测试实践-DAY1

    时间:2017.12.11 地点:软件学院 成员:张玉.周静.张双双 会议内容:讨论题目要求,分配任务 针对第一阶段的任务进行部署,共同学习白盒测试方法,根据自己选择的系统--餐厅网站,针对其中的管理 ...