初级排序算法1-定义排序规则

简介: 初级排序算法-定义排序规则 排序就是将一组对象按照某种逻辑序列重新排列的过程. Table of contents介绍为什么学它排序算法类的模板验证性能评估介绍现在计算机的广泛使用使得数据无处不在,而整理数据的第一步通常就是进行排...

初级排序算法-定义排序规则

排序就是将一组对象按照某种逻辑序列重新排列的过程.


Table of contents

介绍

现在计算机的广泛使用使得数据无处不在,而整理数据的第一步通常就是进行排序

所有的计算机都实现了各种排序算法以供系统和用户使用

为什么学它

即使你只是使用标准库中的排序算法,学习排序算法仍然有三大实际意义

  1. 对排序算法的分析将有助于你全面理解比较算法性能的方法
  2. 类似的技术也能有效解决其他类型的问题
  3. 排序算法常常是我们使用算法解决其他问题的第一步

排序算法类的模板

package algorithms4.sort;

import edu.princeton.cs.algs4.In;

public class Example {

    public static void sort(Comparable[] a){
        //排序算法
    }

    private static boolean less(Comparable v, Comparable w){
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j){
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a){
        //在单行中打印数组
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i] + " ");
        }
        System.out.println();
    }

    public static boolean isSorted(Comparable[] a){
        //测试数组元素是否有序
        for (int i = 0; i < a.length; i++) {
            if (less(a[i], a[i -1])) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {

        //从标准输入读取字符串,将他们排序并输出
        String[] a = new In("需要排序的数据文件").readAllStrings();
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

我们会将排序算法放在类的sort()方法中,该类还将包含辅助函数less类()和exch()(可能还会有其他辅助函数)以及一个示例用例main()

为了区别不同的排序算法,我们为相应的类取了不同的名字,例如Insertion.sort(),Merge.sort(),Quick.sort()等

这个类展示的是数组排序实现的框架,对于我们学习的每种排序算法,我们都会为这样一个类实现一个sort()方法并将example改为算法的名称

验证

通过assert isSorted(a);来确认排序后的数组元素都是有序的,尽管一般都会做简单地测试,并从数学上证明算法的正确性,但是实现每个算法时加上这条语句仍是必要的

如果我们只使用exch()来交换数组的元素,这个测试就足够了

但是当我们直接将值存入数组的方式(也就是原数组不变,得到另一个排序数组)

这条语句就无法提供足够的保证了(例如,凭空造出一个1,2,3数组,哈哈)

性能评估

  1. 运行时间.评估算法的性能,计算各个排序算法在不同的随机输入下的基本操作的次数(包括比较和交换,或者是读写数组的次数)

  2. 在研究排序算法时,我们需要计算比较和交换的数量,对于不交换的算法,我们会计算访问数组的次数

  3. 额外的内存使用

    排序算法的额外内存开销和运行时间是同样重要的

    排序算法可以分为两类

    1. 除了函数调用所需的栈和固定数量的实例变量之外无须额外内存的原地排序算法
    2. 以及需要额外内存来存储另一份数组副本的其他排序算法

数据类型

我们的排序算法模板适用于任何实现了Comparable接口的数据类型,遵循java惯例的好处是,很多你希望排序的数据都实现了comparable接口,例如基本类型,以及String和其他许多高级数据类型,(如file和url)都实现了comparable接口

因此,可以直接使用这些类型的数组作为参数调用我们的排序方法

在创建自己的数据类型时,我们只需要实现Comparable接口就能保证用例代码将其排序

实现comparable接口中的compareTo方法来定义目标对象类型的自然排序规则

如下面的date数据类型(@Data注解转向另一篇博客lombok)

package algorithms4.sort;

import lombok.Data;

@Data
public class DateExample implements Comparable<DateExample> {
    private final int month;
    private final int day;
    private final int year;

    public DateExample(int d, int m, int y){
        day = d;
        month = m;
        year = y;
    }

    @Override
    public int compareTo(DateExample that) {
        if (this.year < that.year) {
            return -1;
        } else if (this.year > that.year) {
            return 1;
        } else if (this.month < that.month) {
            return -1;
        } else if (this.month > that.month) {
            return 1;
        } else if (this.day < that.day) {
            return -1;
        } else {
            return this.day > that.day ? 1 : 0;
        }
    }

    @Override
    public String toString(){
        return year + "/" + month + "/" + day;
    }

}

compareto必须实现一个完整的比较接口

数学意义上

当两个元素满足

1.自反性,对于所有的v,v=v

2.反对称性,有v<w情况的存在,都有v>w的情况存在

3.传递性,如果v<=w,且w<=x,则v<=x

compareto实现了我们的主键抽象,它给出了实现了comparable接口的任意数据类型的对象的大小顺序的定义

目录
相关文章
|
3月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
9天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
50 8
|
9天前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
37 7
|
1月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
51 9
|
1月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
23 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
1月前
|
人工智能 算法 前端开发
无界批发零售定义及无界AI算法,打破传统壁垒,累积数据流量
“无界批发与零售”是一种结合了批发与零售的商业模式,通过后端逻辑、数据库设计和前端用户界面实现。该模式支持用户注册、登录、商品管理、订单处理、批发与零售功能,并根据用户行为计算信用等级,确保交易安全与高效。
|
2月前
|
算法 前端开发 机器人
一文了解分而治之和动态规则算法在前端中的应用
该文章详细介绍了分而治之策略和动态规划算法在前端开发中的应用,并通过具体的例子和LeetCode题目解析来说明这两种算法的特点及使用场景。
一文了解分而治之和动态规则算法在前端中的应用
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
31 0
|
1月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
72 0
|
3月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
41 0