java基础-排序

一.jdk中自带的排序

1.数据的排序Arrays.sort()方法

该方法根据Comparable接口中实现的compareTo()方法进行排序依据

@Test
public void testArraysSort() {
    int[] arr = new int[] { 7, 2, 9, 4, 8, 3, 0 };
    System.out.print("排序前:");
    printArr(arr);
    Arrays.sort(arr);
    System.out.print("排序后:");
    printArr(arr);
}
private static void printArr(int[] arr) {
    System.out.print("[");
    for (int i : arr) {
        System.out.print(i);
            System.out.print(",");
    }
    System.out.println("]");
}

2.Collections.sort(List<T> list)方法

该方法需要List集合中的元素实现Comparable接口(<T extends Comparable<? super T>>)。

@Test
public void testCollectionsSort(){
    List<Integer> list = new ArrayList<Integer>();
    list.add(6);
    list.add(1);
    list.add(9);
    list.add(7);
    list.add(3);
    System.out.println("排序前:"+list);
    Collections.sort(list);
    System.out.println("排序后 :"+list);
}

该方法底层是先将List集合转为数据后再通过Arrays.sort()方法进行排序。

方法源码:

 public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] a = list.toArray();
    Arrays.sort(a);
    ListIterator<T> i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set((T)a[j]);
    }
}

3.HashSet的排序

HashSet通过对象的hashCode方法的返回值进行排序

对象

class HashSetSort{
    private int id;
    private String name;
    //省略getter,setter方法
    public HashSetSort(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public int hashCode() {
        return id;
    }
    @Override
    public String toString() {
        return "name=" + name + "";
    }
}

测试方法

@Test
public void testSetSort(){
    Set<Object> set = new HashSet<Object>();
    set.add(new HashSetSort(3, "a3"));
    set.add(new HashSetSort(2, "a2"));
    set.add(new HashSetSort(4, "a4"));
    set.add(new HashSetSort(5, "a5"));
    set.add(new HashSetSort(1, "a1"));
    System.out.println(set);//[name=a, name=b, name=c, name=d, name=e]
}

二.自定义排序

通用方法

该方法用于输出数据的数据

private static void printArr(int[] arr) {
    StringBuffer sb = new StringBuffer();
    sb.append("[");
    for (int i : arr) {
        sb.append(i);
        sb.append(",");
    }
    sb.deleteCharAt(sb.length() - 1).append("]");
    System.out.println(sb);
}

1.冒泡排序

思路:
  从第一个元素开始如果第一个元素大于第二个元素,则交换位置,然后对比第二个元素与第三个元素,如果第二个元素大于第三个元素则交换位置,一次轮对比到最后一个元素的位置,第一次冒泡完成,获取到了最大值。第二轮则对比到倒数第二个元素,获取到第二大的值。以此类推,直到排序完成。
这里写图片描述

测试代码:

@Test
public void bubbleSort() {
    int[] arr = new int[] { 4, 3, 5, 1, 2 };
    // i表示轮数,因为每轮会查询出一个最大值,第i轮能查询出i个最大值,而只要确定了(i-1)个最大值,剩下的那个自然就是最小值,无需再判断,所以有总共需要(arr.length-1)轮
    for (int i = 0; i < arr.length - 1; i++) {
        //j表示需要比较到的最大索引数,因为第i轮会确定i个最大值,所以每轮为(arr.length-当前轮数)
        for (int j = 0; j + 1 < arr.length - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
            System.out.print(String.format("第%d%d次排序结果为:", i + 1, j + 1));
            printArr(arr);
        }
        System.out.print(String.format("***第%d轮排序完后顺序为:", i + 1));
        printArr(arr);
    }
}

测试结果:

第1轮1次排序结果为:[3,4,5,1,2]
第1轮2次排序结果为:[3,4,5,1,2]
第1轮3次排序结果为:[3,4,1,5,2]
第1轮4次排序结果为:[3,4,1,2,5]
***第1轮排序完后顺序为:[3,4,1,2,5]
第2轮1次排序结果为:[3,4,1,2,5]
第2轮2次排序结果为:[3,1,4,2,5]
第2轮3次排序结果为:[3,1,2,4,5]
***第2轮排序完后顺序为:[3,1,2,4,5]
第3轮1次排序结果为:[1,3,2,4,5]
第3轮2次排序结果为:[1,2,3,4,5]
***第3轮排序完后顺序为:[1,2,3,4,5]
第4轮1次排序结果为:[1,2,3,4,5]
***第4轮排序完后顺序为:[1,2,3,4,5]

2.选择排序

思路
  它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
  选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。
这里写图片描述

测试方法:

@Test
public void selectionSort() {
    int[] arr = new int[] { 4, 3, 5, 1, 2 };
    // i表示轮数,因为每轮会查询出一个最大值,第i轮能查询出i个最小值,而只要确定了(i-1)个最小值,剩下的那个自然就是最大值,无需再判断,所以有总共需要(arr.length-1)轮
    for (int i = 0; i < arr.length - 1; i++) {
        // 记录最小值的索引(默认是当前轮的第一个值)
        int minIndex = i;
        System.out.println(String.format("开始第%d轮,默认最小值为%d", i + 1, arr[minIndex]));
        // 判断最小值与之后每个值得大小
        for (int j = i + 1; j < arr.length; j++) {
            // 如果遍历到的值小于此时记录的最小值,则重新制定最小值的索引为当前遍历到的值得索引
            if (arr[j] < arr[minIndex]) {
                System.out.println(String.format("发现了有更小的值,当前记录的最小值为%d,遍历到的值为%d",
                    arr[minIndex], arr[j]));
                minIndex = j;
            }
        }
        //
        int temp = arr[minIndex];
        arr[minIndex] = arr[i];
        arr[i] = temp;
        System.out.print(String.format("***第%d轮排序完后顺序为:", i + 1));
        printArr(arr);
    }
}

测试结果:

开始第1轮,默认最小值为4
发现了有更小的值,当前记录的最小值为4,遍历到的值为3,最小值的索引为1
发现了有更小的值,当前记录的最小值为3,遍历到的值为1,最小值的索引为3
***第1轮排序完后顺序为:[1,3,5,4,2]
开始第2轮,默认最小值为3
发现了有更小的值,当前记录的最小值为3,遍历到的值为2,最小值的索引为4
***第2轮排序完后顺序为:[1,2,5,4,3]
开始第3轮,默认最小值为5
发现了有更小的值,当前记录的最小值为5,遍历到的值为4,最小值的索引为3
发现了有更小的值,当前记录的最小值为4,遍历到的值为3,最小值的索引为4
***第3轮排序完后顺序为:[1,2,3,4,5]
开始第4轮,默认最小值为4
***第4轮排序完后顺序为:[1,2,3,4,5]

3.插入排序

思路:
  它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
这里写图片描述

测试代码:

@Test
public void insertionSort() {
    int[] arr = new int[] { 4, 3, 5, 1, 2 };
    for (int i = 0; i < arr.length - 1; i++) {
        // 取出已排序好的子数组后的第一个元素
        int temp = arr[i + 1];
        // num为每轮的第n次比较,仅用于查看每次比较的的结果,对排序结果无影响
        // j为默认已经排序完的子数组的最后一个元素的索引
        for (int j = i, num = 1; j >= 0; j--, num++) {
            if (temp > arr[j]) {
                //如果取出值大于比较值,索引排序已完成,进行下一轮排序
                break;
            }
            //如果取出值小于比较值,索引比较值要往后移动
            arr[j + 1] = arr[j];
            arr[j] = temp;
            System.out.print(String.format("第%d轮%d次比较完后顺序为:", i + 1, num));
            printArr(arr);
        }
        System.out.print(String.format("***第%d轮排序完后顺序为:", i + 1));
        printArr(arr);
    }
}

测试结果:

第1轮1次比较完后顺序为:[3,4,5,1,2]
***第1轮排序完后顺序为:[3,4,5,1,2]
***第2轮排序完后顺序为:[3,4,5,1,2]
第3轮1次比较完后顺序为:[3,4,1,5,2]
第3轮2次比较完后顺序为:[3,1,4,5,2]
第3轮3次比较完后顺序为:[1,3,4,5,2]
***第3轮排序完后顺序为:[1,3,4,5,2]
第4轮1次比较完后顺序为:[1,3,4,2,5]
第4轮2次比较完后顺序为:[1,3,2,4,5]
第4轮3次比较完后顺序为:[1,2,3,4,5]
***第4轮排序完后顺序为:[1,2,3,4,5]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值