前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >各种选择+冒泡+插入排序图解

各种选择+冒泡+插入排序图解

作者头像
编程范 源代码公司
发布2019-07-31 11:46:39
4920
发布2019-07-31 11:46:39
举报

排序基础算法之一,属于常见题型。下面说明一下常见的排序算法,看上哪个就用吧!


选择排序:

代码语言:javascript
复制
文字描述:对一个序列A中的元素A[1]~A[n],令i从1到n枚举,进行n趟操作,每趟从待排序部分【i,n】中选择最小的元素,令其与待排序部分的第一个元素A[i]进行交换,这样元素A[i]就会与当前有序区间【1,,i-1】形成新的有序区间【1,i】。于是n趟操作后,元素就会是有序的。
代码语言:javascript
复制
图形描述:
存储状态:
代码语言:javascript
复制
初始序列:{49 27 65 97 76 12 38}
  第1趟:12与49交换:12{27 65 97 76 49 38}
  第2趟:27不动 :12 27{65 97 76 49 38}
  第3趟:65与38交换:12 27 38{97 76 49 65}
  第4趟:97与49交换:12 27 38 49{76 97 65}
  第5趟:76与65交换:12 27 38 49 65{97 76}
  第6趟:97与76交换:12 27 38 49 65 76 97 
  完成

C代码:

代码语言:javascript
复制
void SelectSort(RecordType r[], int length) /*对记录数组r做简单选择排序,length为待排序记录的个数*/
{
    int temp;
    for ( i=0 ; i< length-1 ; i++) //n-1趟排序
    {
        int index=i; //假设index处对应的数组元素是最小的
        for (int j=i+1 ; j < length ; j++)  //查找最小记录的位置
            if (r[j].key < r[index].key )
                index=j;
        if ( index!=i)  //若无序区第一个元素不是无序区中最小元素,则进行交换
        {
            temp     = r[i];
            r[i]     = r[index];
            r[index] = temp;
        }
    }
}

复杂度:

代码语言:javascript
复制
O(n^2)

冒泡排序:

代码语言:javascript
复制
文字描述:它是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!
代码语言:javascript
复制
基本原理:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码语言:javascript
复制
图片描述:

C代码:

代码语言:javascript
复制
void bubbleSort (elemType arr[], int len) {
    elemType temp;
    int i, j;
    for (i=0; i<len-1; i++) //外循环为排序趟数,len个数进行len-1趟
        for (j=0; j<len-1-i; j++) { // 内循环为每趟比较的次数,第i趟比较len-i次
            if (arr[j] > arr[j+1]) { // 相邻元素比较,若逆序则交换(升序为左大于右,降序反之)
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
}

算法复杂度:

代码语言:javascript
复制
O(N^2)

直接插入排序:

代码语言:javascript
复制
文字描述过程:
第1趟插入:将第2个元素插入前面的有序子序列,此时前面只有一个元素,当然是有序的
第2趟比较:将第3个元素插入前面的有序子序列,前面的2个元素是有序的
......
第n-1趟比较:将第n个元素插入前面的有序子序列,前面n-1个元素是有序的
代码语言:javascript
复制
图片描述(第一种):
代码语言:javascript
复制
图片描述(第二种):

java代码:

代码语言:javascript
复制
public static void insertionSort(int[] nums) {
    int temp;
    for(int i = 1; i < nums.length; i++) {
        for(int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; j--) {
            temp = nums[j];
            nums[j] = nums[j + 1];
            nums[j + 1] = temp;
        }
    }
}

复杂度:

代码语言:javascript
复制
O(n^2)

优化:

代码语言:javascript
复制
上面的算法的缺点:在第i-1趟插入时,需要把第i个元素插入到前面的i-1个元素中,该算法总是从i-1个元素开始逐个比较之前的每个元素,直到找到第i个元素的插入位置,这显然没有利用前面0~i-1个元素已经有序的特点。

优化:在0~i-1个有序元素给第i个元素寻找插入的位置时,使用二分查找法可以有效提高查找插入位置的时间效率,经过优化的插入排序称为折半插入排序

折半插入排序:

Java代码:

代码语言:javascript
复制
public static void binaryInsertionSort(int[] nums) {
    for(int i = 1; i < nums.length; i++) {
        int left = 0;
        int right = i - 1;
        int temp = nums[i];
        // 通过二分查找找到插入的位置
        while(left <= right) {
            int mid = (left + right) / 2;
            if(temp > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        // 插入位置之后的元素依次向后移动
        for(int j = i; j > left; j--) {
            nums[j] = nums[j - 1];
        }
        // 更新插入位置的值
        nums[left] = temp;
    }
}

由于排序题中大部分都只需要得到排序的最终结果,而不需要写排序的完整过程(例如冒泡排序,快速排序等过程)因此比赛时强烈建议使用C语言中的库函数qsort或是C++中的sort函数,接下来主讲更简洁的sort函数 1.如何使用sort排序

代码语言:javascript
复制
1.函数的使用必须加上头文件#include<algorithm> 和using namespace std;
2.sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填))
3.通常是sort(a,a+len,cmp())
不写比较函数的话,默认从小到大排序
4.通常与vector容器配合使用(想了解的请点击如下链接)

参考:1044题-[编程拓展]三个字符串的排序-题解(STL—-vector+sort)

2.cmp()实现 (1)从大到小

代码语言:javascript
复制
bool cmp(int a,int b){
    return a>b;
}

(2)结构体数组从小到大(一级排序)

代码语言:javascript
复制
struct node{
    int x;
};
bool cmp(node a,node b){
    return a.x<b.x;
}

(3)结构体数组,先按x从小到大,若x相等,则按y从大到小(二级排序)

代码语言:javascript
复制
struct node{
    int x;
    int y;
};
bool cmp(node a,node b){
    if(a.x!=b.x) return a.x<b.x;
    else return a.y>b.y;
}

(4)结构体里的字符数组,先按x(字典序)从小到大,若x相等,则按y(字典序)从大到小(二级排序)

代码语言:javascript
复制
struct node{
    char x[100];
    char y[100];
};
bool cmp(node a,node b){
    if(a.x!=b.x) return strcmp(a.x,b.x)<0;
    else return strcmp(a.y,b.y)>0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程范 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档