【JAVA数据结构】其他排序(了解即可)

简介: JAVA数据结构 & 其他排序(了解即可)

JAVA数据结构 & 其他排序(了解即可)

1. 计数排序


结合动图不难看出,这里只是对相同数据进行统计并再输出罢了


不适合引用类型,因为我们复制的是同一份,而引用类型应该只是部分相等


其实这种方法排序特别快,但是一旦最大最小值差距太大的话,速度和空间都大大增加!


每个相同的都是新的,因为不靠交换的(并且对应引用(并不一定每个都是一样的,只是判断相等是一部分元素))


所以可以说是稳定的,也可以说不稳定

/**
     * 在稀疏情况下,范围有可能会远大于N ,导致速度极慢空间极大
     * 计数排序,有局限性(必须知道bound限制,或者的自己算)
     * 没有发生交换(除了在获取最大最小值得时候)
     * 时间复杂度 O( max (范围, N))  //可能很稀疏就浪费很多空间了
     * 空间复杂度 O(范围)额外空间
     * @param arr
     * @param bound
     */
//这种是提供范围参数的方法
    public static void countSort(int[] arr, int start, int bound) {
        arr = Arrays.copyOf(arr, arr.length);
        int[] count = new int[bound - start];
        for(int x : arr) {
            count[x - start]++;
        }
        int j = 0;
        for (int i = 0; i <= bound - start - 1; ) {
            while(count[i] == 0) {
                i++;
                if(i > bound - start - 1) {
                    break;
                }
            }
            if(j > arr.length - 1 || i > bound - start - 1) {
                break;
            }
            arr[j++] = i + start;
            count[i]--;
        }
    }
//这是不提供范围,自身自动查找范围的方法
    public static void countSort(int[] arr) {
        int min = arr[0];
        int max = arr[0];
        for (int x : arr) {
            if (max < x) {
                max = x;
            }
            if (min > x) {
                min = x;
            }
        }
        arr = Arrays.copyOf(arr, arr.length);
        int[] count = new int[max - min + 1];
        for (int x : arr) {
            count[x - min]++;
        }
        int j = 0;
        for (int i = 0; i <= max - min; ) {
            while(count[i] == 0) {
                i++;
                if (i > max - min) {
                    break;
                }
            }
            if (j > arr.length - 1 || i > max - min) {
                break;
            }
            arr[j++] = i + min;
            count[i]--;
        }
    }


2. 基数排序


结合动图以及理念不难看出,这里模拟的是我们在比较整数大小用的思想


保证同一位的数排序好,让位数一样在一起,并且完美排列(根据数的比较法排的,大位到小位依排列)


保证【这一位】前面的位都一致,依照【这一位】可以排好。


是赋值罢了


可以说稳定也可以说不稳定

利用队列先进先出的特点,不干扰其顺序【不知道数组大小,才用集合类】

/**
 * 基数排序---->可以不交换不比较
 * 并且!只能用于整形家族
 * 时间 O(N*lgN)
 * 空间 O(N)
 * @param arr
 */
public static void  cardinalSort(int[] arr) {
    arr = Arrays.copyOf(arr, arr.length);
    List<Queue<Integer>> queueList = new ArrayList<>();
    for (int i = 0; i < 20; i++) {
        queueList.add(new LinkedList<>());
    }
    int x = 1;
    int y = 10;
    while(true) {
        for (int i = 0; i < arr.length; i++) {
            int tmp = arr[i] % y / x;
            queueList.get(tmp + 9).offer(arr[i]);
        }
        if(queueList.get(9).size() == arr.length) {
            break;
        }
        int j = 0;
        for (int i = 0; i < 20; i++) {
            while(!queueList.get(i).isEmpty()) {
                arr[j++] = queueList.get(i).poll();
            }
        }
        x *= 10;
        y *= 10;
    }
}


3. 桶排序


桶排序就是将数据按照大小,先大概的分到不同范围区间的桶里面


上面动图是一种方法,按照不同位数放在一起,使用于整数


桶排序的稳定性取决于二级排序方法是用那种

/**
     * 桶排序
     * 思想很简单,只需要分组分别排序即可(哈希思想)
     * 但是需要有一个基础的排序法(也可以结合递归,那样更慢了,原理还不如放在搜索数之中,然后直接中序遍历,或者快速排序)
     * 稳定不稳定取决于二级排序方法是什么
     * 这种方法是强制有规律的分割!并不能在原数组进行”本质“修改,跟计数排序差不多
     * @param arr
     */
    private static final int BUCKET_CAPACITY = 500;//一个桶的范围
    public static void bucketSort(int[] arr) {
        arr = Arrays.copyOf(arr, arr.length);
        //桶的个数
        int[] tmp = Arrays.copyOf(arr, arr.length);
        int min = tmp[0];
        int max = tmp[0];
        for(int x : tmp) {
            if(min > x) {
                min = x;
            }
            if(max < x) {
                max = x;
            }
        }
        int number = (max - min + 1) / BUCKET_CAPACITY + 1;
        int[] count = new int[number];
        List<List<Integer>> list = new ArrayList<>();
        for (int i = 0; i < number; i++) {
            list.add(new ArrayList<>());
        }
        for (int i = 0; i < tmp.length; i++) {
            int index = (tmp[i] - min) / BUCKET_CAPACITY;
            list.get(index).add(tmp[i]);
        }
        for (int i = 0; i < number; i++) {
            Collections.sort(list.get(i));
        }
        int size = 0;
        for (int i = 0; i < number; i++) {
            for (int j = 0; j < list.get(i).size(); j++) {
                arr[size++] = list.get(i).get(j);
            }
        }
    }



4. 搜索树排序

这种方法很明显利用了搜索树的性质,中序遍历必然有序**


这种方法是依照数组构造了一棵搜索树,然后再中序遍历储存在数组了


二叉搜索树的特点就是,左大右小,无非就是拿到是数字小就放左边,拿到的数大就放右边

具体参考《二叉搜索树》章节,还没学到这个方法可先不学!


下面是我截取的需要用到的二叉搜索树代码


public class BinarySearchTree {
    static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val) {
            this.val = val;
        }
    }
    public TreeNode root;
    //普通搜索二叉树,时间复杂度是O(N)最差【单分支】,O(log2N)最优【完全二叉树】
    public void insert(int val) {
        if(root == null) {
            root = new TreeNode(val);
            return;
        }
        TreeNode cur = root;
        TreeNode prev = null;
        while(cur != null) {
            prev = cur;
            if(val <= cur.val) {
                cur = cur.left;
            }else {
                cur = cur.right;
            }
        }if(val <= prev.val) {
            prev.left = new TreeNode(val);
        }else {
            prev.right = new TreeNode(val);
        }
    }
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root != null) {
            list.addAll(inorderTraversal(root.left));
            list.add(root.val);
            list.addAll(inorderTraversal(root.right));
        }
        return list;  
    }
}



/**
     * 搜索树排序
     * 稳定
     * @param arr
     */
    public static void binarySearchTreeSort(int[] arr) {
        arr = Arrays.copyOf(arr, arr.length);
        BinarySearchTree tree = new BinarySearchTree();
        for(int x : arr) {
            tree.insert(x);
        }
        List<Integer> list = tree.inorderTraversal(tree.root);
        int i = 0;
        for(Integer x : list) {
            arr[i++] = x;
        }
    }


文章到此结束!谢谢观看 —>动图来源于网络

可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!


这是我的代码仓库!(在马拉圈的23.2里)代码仓库 排序代码具体位置

目录
相关文章
|
11月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
473 1
|
8月前
|
监控 Java API
Java语言按文件创建日期排序及获取最新文件的技术
这段代码实现了文件创建时间的读取、文件列表的获取与排序以及获取最新文件的需求。它具备良好的效率和可读性,对于绝大多数处理文件属性相关的需求来说足够健壮。在实际应用中,根据具体情况,可能还需要进一步处理如访问权限不足、文件系统不支持某些属性等边界情况。
383 14
|
9月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
436 3
|
11月前
|
存储 Java 编译器
Java 中 .length 的使用方法:深入理解 Java 数据结构中的长度获取机制
本文深入解析了 Java 中 `.length` 的使用方法及其在不同数据结构中的应用。对于数组,通过 `.length` 属性获取元素数量;字符串则使用 `.length()` 方法计算字符数;集合类如 `ArrayList` 采用 `.size()` 方法统计元素个数。此外,基本数据类型和包装类不支持长度属性。掌握这些区别,有助于开发者避免常见错误,提升代码质量。
994 1
|
存储 机器学习/深度学习 算法
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
1021 29
|
Java 程序员
Java 排序神器:Comparable 和 Comparator 该怎么选?
嗨,大家好,我是小米!今天和大家聊一聊Java社招面试中常考的经典问题——Comparable和Comparator的区别。Comparable定义对象的自然排序,适用于单一固定的排序规则;Comparator则是策略接口,用于定义自定义排序规则,适用于多样化或多变的排序需求。掌握这两者的区别是理解Java排序机制的基础,也是面试中的加分题。结合实际项目场景深入探讨它们的应用,能更好地打动面试官。如果你觉得有帮助,欢迎点赞、收藏、分享,期待你的一键三连!我们下期见~ 我是小米,一个喜欢分享技术的程序员,关注我的微信公众号“软件求生”,获取更多技术干货!
209 20
|
存储 人工智能 算法
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
427 10
|
搜索推荐 算法 数据处理
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
304 10
|
搜索推荐 C++
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
342 7
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
255 5

热门文章

最新文章