博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
总结一下常用的排序,冒泡排序,选择排序,快速排序
阅读量:6620 次
发布时间:2019-06-25

本文共 3066 字,大约阅读时间需要 10 分钟。

最近学习了几种排序。

 

(一)冒泡排序:

 实现原理:

比如有一个数组 10,  43,  48,  1,  8,  3,  5,  7,  1,  -21

第一次的第一轮:10小于43,所以10和43不交换位置;

第一次的第二轮:43小于48,所以43和48不交换位置;

第一次的第三轮:48大于1,所以48和1交换位置;变成了  10,  43,  1,  48,  8,  3,  5,  7,  1,  -21

第一次的第四轮:48大于8,所以48和8交换位置;变成了  10,  43,  1,  8,  48,  3,  5,  7,  1,  -21

第一次的第五轮:48大于3,所以48和3交换位置;变成了  10,  43,  1,  8,  3,  48,  5,  7,  1,  -21

第一次的第六轮:48大于5,所以48和5交换位置;变成了  10,  43,  1,  8,  3,  5,  48,  7,  1,  -21

........

以此类推,直到变成了  10,  43,  1,  8,  3,  5,  7,  1,  -21,48。

为什么呢?因为48是该数组中最大的数,第一次就通过这个方法把48放到了数组的最后面,下次就不用再跟48比较了。

所以下一次就不用去跟最后的数比较了,因为最后的数是最大的数。

根据这个规则一直循环下去,经过数组中的数的数量减去1次,就完成了排序。

下面是根据c语言的代码(c中不允许在for循环中定义变量,除了c99标准):

#include
int main(){ int A[10] = { 10,43,48,1,8,3,5,7,1,-21 }, t,i,j; for (i = 0; i < 10 - 1; i++) { for (j = 0; j < 10 - i - 1; j++) //因为后面j加1,所以先要减1 { if (A[j] > A[j + 1]) //前面的数与后面的数比较大小 { t = A[j]; A[j] = A[j + 1]; A[j + 1] = t; } } } for (i = 0; i < 10; i++) { printf("%d ", A[i]); } return 0;}

 

总结:冒泡排序是一种用时间换空间的排序方法,时间复杂度为O(N^2)。

(二)选择排序:

 实现原理:

选择排序就是

将第一个数与他后面数中最小的数互换位置。

将第二个数与他后面数中最小的数互换位置。

将第三个数与他后面数中最小的数互换位置。

.......

直到将数组的数的数量减1的数与他后面数中最小的数互换位置。

选择排序代码(代码是用c++编译的,如果使用c的话就改一下头文件为#include<stdio.h>和for循环内的变量定义在外面):

#include
int main(){ int A[10] = { 10,43,48,1,8,3,5,7,1,-21 }, t, min; for (int i = 0; i<10 - 1; i++) { int index = i;//记录数的位置 min = A[i];//记录数的大小 for (int j = i + 1; j<10; j++) if (min>A[j]) //得到比他小的数,如果没有就是他自己 { min = A[j]; //得到最小数的大小 index = j; //得到最小数的位置 } t = A[i]; //交换位置,没有他自己,没有改变位置 A[i] = min; A[index] = t; } for (int i = 0; i<10; i++) printf("%d ", A[i]); return 0;}

 

 

总结:选择排序的平均时间复杂度为O(N^2)。

注:以上两种排序方法因为时间复杂度较大,所以现在很少使用。

 

(三)快速排序:

实现原理:

以下面代码为例:

将第一个数作为key值保存,也就是10。

然后从右边开始寻找,进入第一个循环,依次向左移,直到找到比key值小的数。

右边第一个数-21比10要小,所以退出第一个循环,第一个值为-21。数组变成  -21,  43,  48,  1,  8,  3,  5,  7,  1,  -21。

然后从左边开始寻找,进入第一个循环,依次向左移,直到找到比key值小的数。

左边第一个数10与key值10相等,继续循环。

左边第二个数43比10要大,所以退出第二个循环,数组变成  -21,  43,  48,  1,  8,  3,  5,  7,  1,  43。

因为左边和右边位置还不相同,所以重新进入第一个循环第一个循环(i<j的意义)。

.......

以此类推

一直到数组为   -21,  1,  7,  1,  8,  3,  5,  7,  48,  43。

退出循环。此时i等于j(位置相同)。

i和j在第二个7的位置(如果不懂可以在每次数组循环后打印一次数组查看数组顺序,和查看一下i和j的位置)。

然后第二个7的位置上的值为10。

此时10的左边的数一定小于10,10右边的数一定大于10。

然后左边的数和右边的数分别进入递归,根据这种思想方法去排序,直到完成排序退出递归。

代码如下:

#include
using namespace std;void QSort(int left, int right, int *A){ if (left > right)return;//直到数组中只有唯一一个数,退出递归。 int i = left; int j = right; int key = A[left]; while (i
= A[i])i++;//从左边开始,找到比key大的数。 A[j] = A[i]; } A[i] = key;//重新获得key的值。 QSort(left, i - 1, A);//排列左边的数。 QSort(i + 1, right, A);//排列右边的数。}int main(){ int A[10] = { 10,43,48,1,8,3,5,7,1,-21 }; QSort(0, 9, A); for (int i = 0; i<10; i++) printf("%d ", A[i]); return 0;}

 

总结:快速排序的时间复杂度为O(N),相比于前两种排序的使用时间要少很多,在很多复杂的排序中经常用到。

 

**以上有什么错误还望指出,希望我们共同学习。**

 

转载于:https://www.cnblogs.com/zacksungy/p/6947393.html

你可能感兴趣的文章
高效编程工具
查看>>
dazzle简介
查看>>
struts2文件下载
查看>>
MFC UI 美化
查看>>
Java实现几种简单的重试机制
查看>>
discuz表结构详细版
查看>>
Git- Fatal: cannot do a partial commit during a merge
查看>>
Rust lang Helloworld
查看>>
Zato学习笔记1 安装
查看>>
elasticsearch开发文档(一)——安装与运行
查看>>
sql删除多个字段重复数据有主键和没主键解决方法(mysql)
查看>>
焦烈焱_云与移动互联时代的企业应用架构
查看>>
GCRetractableSectionController
查看>>
Litepal中主键id的类型
查看>>
FreeBSD 10.1环境下apache2.4配置ssl实现https
查看>>
基于面向对象(抽象数据类型)风格的kwic实现
查看>>
PHP钩子是什么?
查看>>
Android应用层到Framework到HAL再到驱动层的整个流程分析
查看>>
进度条,颜色选取
查看>>
图解正向代理、反向代理、透明代理
查看>>