【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里)代码仓库 排序代码具体位置

s:103
+关注
目录
打赏
0
0
0
0
34
分享
相关文章
|
5月前
|
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
67 1
|
5月前
|
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
118 2
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
129 2
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
80 29
Java 排序神器:Comparable 和 Comparator 该怎么选?
嗨,大家好,我是小米!今天和大家聊一聊Java社招面试中常考的经典问题——Comparable和Comparator的区别。Comparable定义对象的自然排序,适用于单一固定的排序规则;Comparator则是策略接口,用于定义自定义排序规则,适用于多样化或多变的排序需求。掌握这两者的区别是理解Java排序机制的基础,也是面试中的加分题。结合实际项目场景深入探讨它们的应用,能更好地打动面试官。如果你觉得有帮助,欢迎点赞、收藏、分享,期待你的一键三连!我们下期见~ 我是小米,一个喜欢分享技术的程序员,关注我的微信公众号“软件求生”,获取更多技术干货!
51 20
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
44 10
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
63 10
|
2月前
|
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
55 7
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
67 5
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
79 6
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等