码迷,mamicode.com
首页 > 编程语言 > 详细

详解桶排序以及排序内容大总结(1)

时间:2020-01-15 14:07:30      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:性问题   dag   git   时间   base   tab   特殊   比较运算符   pow   

比较器的使用

1) 比较器的实质就是重载比较运算符

2) 比较器可以很好的应用在特殊标准的排序上

3) 比较器可以很好的应用在根据特殊标准排序的结构上

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.TreeSet;

public class Code03_Comparator {

    public static class Student {
        public String name;
        public int id;
        public int age;

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

    public static class IdAscendingComparator implements Comparator<Student> {
        // 返回负数的时候,第一个参数排在前面。返回正数的时候,第二个参数排在前面。
        // 返回0的时候,谁在前面无所谓。
        @Override
        public int compare(Student o1, Student o2) {
            return o1.id - o2.id;
        }
    }

    public static class IdDescendingComparator implements Comparator<Student> {
        
        @Override
        public int compare(Student o1, Student o2) {
            return o2.id - o1.id;
        }
    }

    public static class AgeAscendingComparator implements Comparator<Student> {

        @Override
        public int compare(Student o1, Student o2) {
            return o1.age - o2.age;
        }
    }

    public static class AgeDescendingComparator implements Comparator<Student> {

        @Override
        public int compare(Student o1, Student o2) {
            return o2.age - o1.age;
        }
    }

    public static void printStudents(Student[] students) {
        for (Student student : students) {
            System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
        }
    }

    public static void printArray(Integer[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static class MyComp implements Comparator<Integer> {

        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    }

    public static void main(String[] args) {
        Student student1 = new Student("A", 2, 23);
        Student student2 = new Student("B", 3, 21);
        Student student3 = new Student("C", 1, 22);

        Student[] students = new Student[] { student1, student2, student3 };

        Arrays.sort(students, new IdAscendingComparator());
        printStudents(students);

        Arrays.sort(students, new IdDescendingComparator());
        printStudents(students);

        Arrays.sort(students, new AgeAscendingComparator());
        printStudents(students);

        Arrays.sort(students, new AgeDescendingComparator());
        printStudents(students);

        PriorityQueue<Student> maxHeapBasedAge = new PriorityQueue<>(new AgeDescendingComparator());
        maxHeapBasedAge.add(student1);
        maxHeapBasedAge.add(student2);
        maxHeapBasedAge.add(student3);
        while (!maxHeapBasedAge.isEmpty()) {
            Student student = maxHeapBasedAge.poll();
            System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
        }

        PriorityQueue<Student> minHeapBasedId = new PriorityQueue<>(new IdAscendingComparator());
        minHeapBasedId.add(student1);
        minHeapBasedId.add(student2);
        minHeapBasedId.add(student3);
        while (!minHeapBasedId.isEmpty()) {
            Student student = minHeapBasedId.poll();
            System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
        }

        TreeSet<Student> treeAgeDescending = new TreeSet<>(new AgeDescendingComparator());
        treeAgeDescending.add(student1);
        treeAgeDescending.add(student2);
        treeAgeDescending.add(student3);

        Student studentFirst = treeAgeDescending.first();
        System.out.println("Name : " + studentFirst.name + ", Id : " + studentFirst.id + ", Age : " + studentFirst.age);

        Student studentLast = treeAgeDescending.last();
        System.out.println("Name : " + studentLast.name + ", Id : " + studentLast.id + ", Age : " + studentLast.age);
    }
}

桶排序思想下的排序

1) 计数排序

2) 基数排序

分析:

1) 桶排序思想下的排序都是不基于比较的排序

2) 时间复杂度为O(N),额外空间负载度O(M)

3) 应用范围有限,需要样本的数据状况满足桶的划分

    // only for no-negative value
    public static void radixSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        radixSort(arr, 0, arr.length - 1, maxbits(arr));
    }

    public static int maxbits(int[] arr) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
        }
        int res = 0;
        while (max != 0) {
            res++;
            max /= 10;
        }
        return res;
    }

    //arr[begin,end]排序
    public static void radixSort(int[] arr, int begin, int end, int digit) {
        final int radix = 10;
        int i = 0, j = 0;

        int[] bucket = new int[end - begin + 1]; //有多少个数准备多少辅助空间
        for (int d = 1; d <= digit; d++) { //有多少位就进出多少次
            int[] count = new int[radix];
            for (i = begin; i <= end; i++) { //10个空间 count[0] 当前位(d位)是0的数字有多少个
                j = getDigit(arr[i], d);
                count[j]++;
            }
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
            for (i = end; i >= begin; i--) {
                j = getDigit(arr[i], d);
                bucket[count[j] - 1] = arr[i];
                count[j]--;
            }
            for (i = begin, j = 0; i <= end; i++, j++) {
                arr[i] = bucket[j];
            }
        }
    }

    public static int getDigit(int x, int d) {
        return ((x / ((int) Math.pow(10, d - 1))) % 10);
    }

排序算法的稳定性及其汇总

同样值的个体之间,如果不因为排序而改变相对次序,就是这个排序是有稳定 性的;否则就没有。

不具备稳定性的排序:

选择排序、快速排序、堆排序

具备稳定性的排序:

冒泡排序、插入排序、归并排序、一切桶排序思想下的排序

目前没有找到时间复杂度0(N*logN),额外空间复杂度0(1),又稳定的排序。

常见的坑

1, 归并排序的额外空间复杂度可以变成0(1),但是非常难,不需要掌握,有兴 趣可以搜“归并排序内部缓存法”

2, “原地归并排序”的帖子都是垃圾,会让归并排序的时间复杂度变成0(92)

3, 快速排序可以做到稳定性问题,但是非常难,不需要掌握,可以搜“01 stable sort”

4, 所有的改进都不重要,因为目前没有找到时间复杂度0(N*logN),额外空间复 杂度0(1),又稳定的排序。

5, 有一道题目,是奇数放在数组左边,偶数放在数组右边,还要求原始的相对 次序不变,碰到这个问题,可以怼面试官。

工程上对排序的改进

1) 充分利用O(N* l ogN)和0 (N“)排序各自的优势

稳定性的考虑

详解桶排序以及排序内容大总结(1)

标签:性问题   dag   git   时间   base   tab   特殊   比较运算符   pow   

原文地址:https://www.cnblogs.com/wwj99/p/12196081.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!