Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >排序之简单排序

排序之简单排序

作者头像
Rochester
发布于 2020-09-01 03:12:46
发布于 2020-09-01 03:12:46
43800
代码可运行
举报
文章被收录于专栏:牛人NR牛人NR
运行总次数:0
代码可运行

简单排序

1. Comparable接口介绍

在元素之间进行比较,而Java提供了一个接口Comparable就是用来定义排序规则的。

需求:

1.定义一个学生类Student,具有年龄age和姓名username两个属性,并通过Comparable接口提供比较规则;

2.定义测试类Test,在测试类Test中定义测试方法Comparable getMax(Comparable c1,Comparable c2)完成测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.comparable;

/**
 * 学生类
 * @author silentCow
 * @Date 2020/8/9 8:44
 */
public class Student implements Comparable<Student>{

    private int age;
    private String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Student() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 定义比较规则
     * @param o
     * @return
     */
    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.comparable;

/**
 * 测试类
 * @author silentCow
 * @Date 2020/8/9 8:45
 */
public class StudentTest {

    public static void main(String[] args) {
        // 创建Student对象,并调用getMax方法,进行测试
        Student stu1 = new Student(15, "张三");
        Student stu2 = new Student(16, "李四");

        Comparable max = getMax(stu1, stu2);
        System.out.println(max);
    }

    public static Comparable getMax(Comparable c1,Comparable c2) {
        int result = c1.compareTo(c2);
        // 如果 result < 0,则 c1 比 c2 小;
        // 如果 result = 0,则 c1 和 c2 相等;
        // 如果 result > 0,则 c1 比 c2 大;
        if (result >= 0) {
            return c1;
        } else {
            return c2;
        }
    }

}

2. 冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

需求:

排序前:{4,5,6,3,2,1}

排序后:{1,2,3,4,5,6}

排序原理:

  1. 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置。
  2. 对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值

冒泡排序API设计:

代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.comparable;

/**
 * @author silentCow
 * @Date 2020/8/9 9:11
 */
public class Bubble {

    //对数组a中的元素进行排序
    public static void sort(Comparable[] a) {
        for (int i = a.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (greater(a[j], a[j + 1])) {
                    exch(a, j, j + 1);
                }
            }
        }
    }


    //比较v元素是否大于w元素
    private static boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) > 0;
    }

    // 数组元素i和j交换位置
    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.test;

import cn.silentcow.comparable.Bubble;

import java.util.Arrays;

/**
 * @author silentCow
 * @Date 2020/8/9 9:14
 */
public class SortTest {
    public static void main(String[] args) {
        Integer[] a = {4, 5, 6, 3, 2, 1};
        Bubble.sort(a);
        System.out.println(Arrays.toString(a));
    }
}

冒泡排序的时间复杂度分析 冒泡排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码,所以,我们分析冒泡排序的时间复杂度,主要分析一下内层循环体的执行次数即可。

在最坏情况下,也就是假如要排序的元素为{6,5,4,3,2,1}逆序,那么:

元素比较的次数为:

(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

元素交换的次数为:

(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

总执行次数为:

(N^2/2-N/2)+(N^2/2-N/2)=N^2-N;

按照大O推导法则,保留函数中的最高阶项那么最终冒泡排序的时间复杂度为O(N^2).

3. 选择排序

选择排序是一种更加简单直观的排序方法。

需求:

排序前:{4,6,8,7,9,2,10,1}

排序后:{1,2,4,5,7,8,9,10}

排序原理:

1.每一次遍历的过程中,都假定第一个索引处的元素是最小值,和其他索引处的值依次进行比较,如果当前索引处的值大于其他某个索引处的值,则假定其他某个索引出的值为最小值,最后可以找到最小值所在的索引

2.交换第一个索引处和最小值所在的索引处的值

选择排序API设计:

类名

Selection

构造方法

Selection():创建Selection对象

成员方法

1.public static void sort(Comparable[] a):对数组内的元素进行排序 2.private static boolean greater(Comparable v,Comparable w):判断v是否大于w 3.private static void exch(Comparable[] a,int i,int j):交换a数组中,索引i和索引j处的值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.comparable;

/**
 * @author silentCow
 * @Date 2020/8/9 12:34
 */
public class Selection {

    //对数组a中的元素进行排序
    public static void sort(Comparable[] a) {
        for (int i = 0; i <= a.length - 2; i++) {
            //假定本次遍历,最小值所在的索引是i
            int minIndex = i;
            for (int j = i + 1; j < a.length; j++) {
                if (greater(a[minIndex], a[j])) {
                    //跟换最小值所在的索引
                    minIndex=j;
                }
            }
            //交换i索引处和minIndex索引处的值
            exch(a, i, minIndex);
        }
    }

    //比较v元素是否大于w元素
    private static boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) > 0;
    }

    //数组元素i和j交换位置
    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.test;

import cn.silentcow.comparable.Selection;

import java.util.Arrays;

/**
 * @author silentCow
 * @Date 2020/8/9 12:35
 */
public class SelectionTest {

    public static void main(String[] args) {
        Integer[] a = {4, 6, 8, 7, 9, 2, 10, 1};
        Selection.sort(a);
        System.out.println(Arrays.toString(a));
    }

}

选择排序的时间复杂度分析:

选择排序使用了双层for循环,其中外层循环完成了数据交换,内层循环完成了数据比较,所以我们分别统计数据交换次数和数据比较次数:

数据比较次数:

(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

数据交换次数:

N-1

时间复杂度:N^2/2-N/2+(N-1)=N^2/2+N/2-1;

根据大O推导法则,保留最高阶项,去除常数因子,时间复杂度为O(N^2);

4. 插入排序

插入排序(Insertion sort)是一种简单直观且稳定的排序算法

需求:

排序前:{4,3,2,10,12,1,5,6}

排序后:{1,2,3,4,5,6,10,12}

排序原理:

1.把所有的元素分为两组,已经排序的和未排序的;

2.找到未排序的组中的第一个元素,向已经排序的组中进行插入;

3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位;

插入排序API设计:

插入排序代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.comparable;

/**
 * @author silentCow
 * @Date 2020/8/9 15:08
 */
public class Insertion {

    // 对数组a中的元素进行排序
    public static void sort(Comparable[] a) {

        for (int i = 0; i < a.length; i++) {
            //当前元素为a[i],依次和i前面的元素比较,找到一个小于等于a[i]的元素
            for (int j = i; j > 0; j--) {
                if (greater(a[j - 1], a[j])) {
                    // 交换元素
                    exch(a, j - 1, j);
                } else {
                    // 找到了该元素,结束
                    break;
                }
            }
        }

    }

    //比较v元素是否大于w元素
    private static boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) > 0;
    }

    // 数组元素i和j交换位置
    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.silentcow.test;

import cn.silentcow.comparable.Insertion;

import java.util.Arrays;

/**
 * @author silentCow
 * @Date 2020/8/9 15:08
 */
public class InsertionTest {
    public static void main(String[] args) {
        Integer[] arr = {4, 3, 2, 10, 12, 1, 5, 6};
        Insertion.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

插入排序的时间复杂度分析

插入排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码,所以,我们分析插入排序的时间复杂度,主要分析一下内层循环体的执行次数即可。

最坏情况,也就是待排序的数组元素为{12,10,6,5,4,3,2,1},那么:

比较的次数为:

(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

交换的次数为:

(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2;

总执行次数为:

(N^2/2-N/2)+(N^2/2-N/2)=N^2-N;

按照大O推导法则,保留函数中的最高阶项那么最终插入排序的时间复杂度为O(N^2).

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
一文弄懂七种排序算法
本文介绍了七种经典排序算法,包括冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序以及堆排序,并且讨论了各种算法的进一步改进,在文章最后还对所有算法的时间和空间复杂度作了一个总结。
zhayujie
2020/06/16
1.1K0
经典算法巡礼(三) -- 排序之插入排序
插入排序,与之前的冒泡排序和选择排序一样,其名称就说明了她的原理。所谓插入排序,就是对于数组中未排序的元素,依次遍历寻找合适的位置并插入到已排序的子数组中。当数组中没有未排序的元素时,插入排序即完成。
jiezhu
2018/09/02
3300
动图解析面试常见排序算法(上)
冒泡排序是一种非常简单的初级排序算法,它每次比较相邻的两个元素,如果顺序错误就进行交换.由于最小的元素是经由不断交换慢慢浮到顶端的,所以叫做冒泡排序.
周三不加班
2019/06/04
4720
动图解析面试常见排序算法(上)
当初为什么不好好学习算法?
排序是一个非常经典的问题,它以一定的顺序对一个数组(或一个列表)中的项进行重新排序(可以进行比较的,例如整数,浮点数,字符串等)。
行百里er
2020/12/02
4150
当初为什么不好好学习算法?
简单排序
选择排序降低了交换次数,但是比较次数仍然很多,当数据量比较少,或者基本上有序的时候,使用选择排序。 对于其他情况,应该选择插入排序。
悠扬前奏
2019/05/31
3510
排序算法总结
概述  本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码,包括选择排序、插入排序、归并排序、希尔排序、快速排序等。算法性能比较如下图所示: 选择排序 种最简单的排序算
Kevin_Zhang
2018/07/05
7430
一文搞定选择排序算法
选择排序使用了双层for循环;如果看过我上一篇文章的话,可以很快的知道一些技巧,双层for循环的时间复杂度是: O(N2) O(N^{2}) O(N2)
手撕代码八百里
2020/07/28
3360
经典算法巡礼(二) -- 排序之选择排序
选择排序,如冒泡排序一样,从名字中即可大概猜测其排序的原理。其工作原理就是从未排序的数组中选出最大(小)的元素,将其放置至数组的首(尾)部,重复此过程直至没有未排序的子数组。
jiezhu
2018/09/02
4610
经典算法巡礼(一) -- 排序之冒泡排序
事实上,她重复地遍历需要排序的元素,一次比较相邻的两个元素,如果不满足预先定义的比较条件,则交换;否则继续下一组元素比较,直至遍历完成需要排序的所有元素。当然,遍历需要排序的元素需要重复进行,直到没有需要排序的元素为止。遍历需要排序的元素时,每一次交换不满足顺序条件的元素就如同气泡一样,从元素序列的一端慢慢“上升”到序列的另一端,此现象如同水中冒气泡一样,此排序算法以此得名。
jiezhu
2018/09/02
3580
一文搞定冒泡排序算法
本文是第一站,大战冒泡排序。你还在为每次写排序算法的时候发愁吗? 喝了本专栏,保证你能手撸冒泡排序。
手撕代码八百里
2020/07/28
8770
第2章 排序
排序是将一组数据按照某种逻辑重新排列的过程。相对比较常用,在考虑排序算法时,我们往往要考虑以下几个方面:
用户7032969
2023/05/09
4080
第2章 排序
图文并茂的排序算法
本文给出常见的几种排序算法的原理以及java实现,包括常见的简单排序和高级排序算法,以及其他常用的算法知识。
用户1212940
2022/04/13
2210
图文并茂的排序算法
【JAVA-Day31】深入解析冒泡、选择和插入排序在数组排序中的应用
在计算机科学和算法领域,排序是一个重要而广泛应用的问题。本博文将深入研究冒泡排序、选择排序和插入排序这三种经典的排序算法,并探讨它们在不同应用场景中的应用。我们将分析它们的工作原理、性能特点以及如何在实际项目中选择合适的排序算法。同时,我们也会介绍一些优化和改进方法,以及未来趋势中的现代排序算法。
默 语
2024/11/20
2720
【JAVA-Day31】深入解析冒泡、选择和插入排序在数组排序中的应用
八大排序算法
​ 八大排序算法是面试经常考到的,尤其是快排,希尔排序和归并也是经常会让写代码的题目,其实只要用一句话说明了他们的原理我们写起代码就没那么困难。 冒泡排序 思想:有 n 个数我们就进行 n-1 趟排序,每一趟我们都选取最大的一个数放到已经排序的位置即可。 伪代码:两个 For 循环,外层表示要进行的趟数,内层则是找出最大的数,找最大的数的方法就是比较、交换。 时间复杂度:O(n2) 空间复杂度:O(n) 代码: package Sorting; import org.junit.jupiter.ap
lwen
2018/04/17
9390
八大排序算法
普林斯顿大学算法公开课笔记——选择排序 普林斯顿大学算法公开课笔记——选择排序
简单选择排序的特点是交换移动次数很少(至多n-1次),其时间复杂度为 O(n²) (时间主要花在比较上,总的比较次数为N=(n-1)+(n-2)+…+1=n*(n-1)/2),与冒泡排序一样,但性能上优于冒泡。
尾尾部落
2018/09/04
6270
排序(Sort) 原
排序是计算机程序设计中的一种重要操作。如果数据能够根据某种规则排序,就能大大挺高数据处理的算法效率。
云飞扬
2019/03/12
1.1K0
排序(Sort)
                                                                            原
十大排序算法详解(一)冒泡排序、选择排序、插入排序、快速排序、希尔排序[通俗易懂]
  冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。整个过程如同气泡冒起,因此被称作冒泡排序。   冒泡排序的步骤是比较固定的:
全栈程序员站长
2022/09/14
8520
十大排序算法详解(一)冒泡排序、选择排序、插入排序、快速排序、希尔排序[通俗易懂]
疯狂java笔记之常用的内部排序
在计算机程序开发过程中,经常需要一组数据元素(或记录)按某个关键字进行排序,排序完成的序列可用于快速查找相关记录。
HelloJack
2018/08/28
8140
疯狂java笔记之常用的内部排序
Java数据结构与算法--简单排序
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
颍川
2019/11/21
3690
简单排序
排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要我们手动实现,毕竟每种语言的类库中都有n多种关于排序算法的实现。但是了解这些精妙的思想对我们还是大有裨益的。冒泡,插入这三种排序是最简单的排序,本文将主要讲解这两种排序思想。
AI那点小事
2020/04/20
2980
简单排序
相关推荐
一文弄懂七种排序算法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验