排序算法(Gif动图演示)
冒牌排序(BubbleSort)
冒泡排序是一种比较简单的排序算法,它循环走过需要排序的元素,依次比较相邻的两个元素,如果顺序错误就交换,直至没有元素交换,完成排序。
若对n个人进行排序,我们需要n-1次比较,所以第k次比较需要进行n-k次比较。排序算法通过以数据对象的两两比较作为关键,所以可以得出,冒泡排序需要进行的
比较次数为:(n-1) + (n-2) + ... + 1 = n*(n-1) / 2,因此冒泡排序的时间复杂度为O(n^2)。
算法简介:
1.比较相邻的元素,前一个比后一个大(或者前一个比后一个小)调换位置
2.每一对相邻的元素进行重复的工作,从开始对一直到结尾对,这步完成后,结尾为做大或最小的数.
3.针对除了最后一个元素重复进行上面的步骤。
4.重复1-3步骤直到完成排序
动画演示:
代码如下
#include<stdio.h>
void BuddleSort(int a[],int n){
for(int i=0;i<n-1;i++){
for( int j=0;j<n-i-1;j++){
if(a[j]>a[j+1]){
int swap=a[j];
a[j]=a[j+1];
a[j+1]=swap;
}
}
}
}
int main(){
int a[]={6, 9,8,4,5,2,1,3,7};
int n=sizeof(a)/sizeof(int);
BuddleSort(a,n);
printf("冒泡排序结果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
冒牌排序改进版:鸡尾酒排序
鸡尾酒排序:又名为定向冒泡排序,相比较于传统的冒泡排序改进方法就是加入一个标志性变量exchange,用于标志某次排序过程中
是否由数据交换,若某一次排序没有进行数据交换,则说明数据已经排列好,可以立刻结束排序,避免不必要的后续比较过程,从而提高性能。
算法描述:每次排序进行正向和反向冒泡一次得到两个终值(最大值和最小值)。
代码如下
#include<stdio.h>
void BuddleSort(int a[],int n)
{
int left=0; //设置变量初始值
int right=n-1;
int swap,j;
while(left<right){
for(j=left;j<right;j++)//正向冒泡,找出最大值
{
if(a[j]>a[j+1])
{
swap=a[j];
a[j]=a[j+1];
a[j+1]=swap;
}
}
right--; //前移一位
for(int j=right;j>left;j--)//反向冒泡找出最小值
{
if(a[j-1]>a[j])
{
swap=a[j];
a[j]=a[j-1];
a[j-1]=swap;
}
}
left++; //修改left值。后移一位
}
}
int main()
{
int a[]={7,8,4,2,9,5,6,1,3};
int n=sizeof(a)/sizeof(int);
BuddleSort(a,n);
printf("鸡尾酒排序结果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
选择排序(SelectSort)
选择排序是一种简单直观的排序算法,工作原理为:在未排序的序列中找出最小(大)元素与第一个位置的元素交换位置
注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
然后在剩下的元素中再找最小(大)元素与第二个元素的位置交换,依此类推,直到所有元素排序排序完成。根据上述描述,一共进行n-1趟比较后,就能完成整个排队过程。我们可以知道,第k趟比较需要进行的数组元素的两两比较的次数为n-k次,所以共需要的比较次数为n*(n-1) / 2,因此选择排序算法的时间复杂度与冒泡排序一样,也为O(n^2)。
算法简介:
1.初始状态:序列为无序状态。
2.第1次排序:从n个元素中找出最小(大)元素与第1个记录交换
3.第2次排序:从n-1个元素中找出最小(大)元素与第2个记录交换
4.第i次排序:从n-i+1个元素中找出最小(大)元素与第i个记录交换
5.以此类推直到排序完成
动画演示:
代码如下
#include<stdio.h>
void SelectSort(int a[],int n)
{
for(int i=0;i<n-1;i++)
{
int min=i; //存放数组最小值的位置
for(int j=i+1;j<n;j++)
{
if(a[j]<a[min]){
min=j; //找出最小值,并记录位置
}
}
if(min!=i) //最小元素与第i个元素互换位置
{
int swap=a[min];
a[min]=a[i];
a[i]=swap;
}
}
}
int main()
{
int a[]={8,9,7,1,5,4,2,3,6};
int n=sizeof(a)/sizeof(int);
SelectSort(a,n);
printf("选择排序结果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
插入排序(InsertSort)
插入排序是一种简单直观的排序算法,工作原理为构建有序序列,对于未排序元素,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间,直到排序完成,如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。理解了插入排序的思想后,我们便能够得到它的时间复杂度。对于n个元素,一共需要进行n-1轮比较,而第k轮比较需要进行k次数组元素的两两比较,因此共需要进行的比较次数为:1 + 2 + ... + (n-1),所以插入排序的时间复杂度同冒泡排序一样,也为O(n^2)。
算法简介:
1.从第一个元素开始,该元素可认为已排序。
2.取出下一个元素,在排序好的元素序列中从后往前扫描
3.如果元素(已排序)大于新元素,将该元素移到下一位置
4.重复3.直到找到已排序的元素小于或等于新元素的位置
5.将新元素插入该位置后
6.重复2-5直到排序完成
动画演示:
代码如下
#include<stdio.h>
void InsertSort(int a[],int n)
{
for(int i=0;i<n;i++)
{
int j=i-1;
if(a[i]<a[i-1]){ //若第i个元素小于第i-1个元素,移动有序序列插入------大于的话则直接插入
int swap=a[i]; //存储将要排序的元素
a[i]=a[i-1]; //向后移动一个元素
while(swap<a[j])//查询将要插入的位置
{
a[j+1]=a[j];
j--; //元素后移
}
a[j+1]=swap;//循环结束 插入到指定位置
}
}
}
int main() {
int a[] = { 9,7,8,2,5,1,3,6,4};
int n = sizeof(a)/sizeof(int);
InsertSort(a, n);
printf("排序好的数组为:");
for (int i = 0; i < n; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
还有几种经典的排序算法没有写出,后续将补充,有不足之处还请指出。谢谢
排序算法(Gif动图演示)的更多相关文章
- 转发自:一像素 十大经典排序算法(动图演示)原链接:https://www.cnblogs.com/onepixel/articles/7674659.html 个人收藏所用 侵删
原链接:https://www.cnblogs.com/onepixel/articles/7674659.html 个人收藏所用 侵删 0.算法概述 0.1 算法分类 十种常见排序算法可 ...
- 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)
一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...
- 八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 简单插 ...
- 八大排序算法——插入排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 例如从小到大排序: 1. 从第二位开始遍历, 2. 当前数(第一趟是第二位数)与前面的数依次比较,如果前面的数大于当前数,则将这个数放在当前数的位置上,当前数的下标-1 ...
- 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...
- 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1. 向上归并排序的时候,需要一个暂存数组用来排序, 2. 将 ...
- 八大排序算法——快速排序(动图演示 思路分析 实例代码Java 复杂度分析)
一.动图演示 二.思路分析 快速排序的思想就是,选一个数作为基数(这里我选的是第一个数),大于这个基数的放到右边,小于这个基数的放到左边,等于这个基数的数可以放到左边或右边,看自己习惯,这里我是放到了 ...
- 八大排序算法——冒泡排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 1. 相邻两个数两两相比,n[i]跟n[j+1]比,如果n[i]>n[j+1],则将连个数进行交换, 2. j++, 重复以上步骤,第一趟结束后,最大数就会被确定 ...
- 八大排序算法——选择排序(动图演示 思路分析 实例代码Java 复杂度分析)
一.动图演示 二.思路分析 1. 第一个跟后面的所有数相比,如果小于(或小于)第一个数的时候,暂存较小数的下标,第一趟结束后,将第一个数,与暂存的那个最小数进行交换,第一个数就是最小(或最大的数) ...
- JS十种经典排序算法,纯动画演示,学会了怼死面试官!
十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过比较来决定 ...
随机推荐
- 百度UEditor的config.json
配合自己修改的.net core DLL使用 /* 前后端通信相关的配置,注释只允许使用多行方式 */ { /* 上传图片配置项 */ "imageActionName": &qu ...
- 视频信号中xyz的提取
视频信号中xyz的提取 `timescale 1ns / 1ps /////////////////////////////////////////////////////////////////// ...
- qt5程序打包含qml
Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,如果自己去复制dll,很可能丢三落四,导致exe在别的电脑里无法正常运行. 因此 Qt 官方开发环境里自带了一 ...
- htm,css,javascript及其他的注释方式
转自:http://www.cnblogs.com/dapeng111/archive/2012/12/23/2829774.html 一.HTML的注释方法<!-- html注释:START ...
- URLConnection(互联网)
一.urlconnection连接Servlet 1:> URL请求的类别: 分为二类,GET与POST请求.二者的区别在于: ...
- Unity Graphics(一):选择一个光照系统
原文链接 Choosing a Lighting Technique https://unity3d.com/learn/tutorials/topics/graphics/choosing-ligh ...
- mysql error(2003) 10060的再解决
前段时间在window虚拟机上处理过这样的问题 现在在linux上也遇到了这样的问题一项一项的排查 1.网络问题,ping的通 但是telnet (ip) (端口号)失败,telnet(ip)都失败 ...
- IIS Express 域认证问题(https://stackoverflow.com/questions/4762538/iis-express-windows-authentication)
option-1: edit \My Documents\IISExpress\config\applicationhost.config file and enable windowsAuthent ...
- photo型的object转byte[]
IEnumerable en = (IEnumerable) myObject; byte[] myBytes = en.OfType<byte>().ToArray(); TypeCon ...
- TCP流量控制
TCP的流量控制,是为了更好的传输数据,控制流量不要发送太快而至于接收端没有足够的缓存的接收. 利用滑动窗口,可以很方便的控制传输 rwnd:可以控制接收窗口大小.ACK代表确认位,ack代表确认字段 ...