常用排序算法(Java描述)

 代码如下:

package cn.ganlixin.sort;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Test;

import java.util.Objects;

public class SortTest {

    @Test
    public void testBubbleSort() {
        Person[] arr = new Person[4];
        arr[0] = new Person(5, "abc");
        arr[1] = new Person(3, "xyz");
        arr[2] = new Person(7, "qaq");
        arr[3] = new Person(1, "lol");

        // bubbleSort(arr);

        // selectSort(arr);

        // insertSort(arr);

        // int[] gapList = {7, 5, 3, 1};
        // shellSort(arr, gapList);

        // quickSort(arr, 0, arr.length - 1);

        mergeSort(arr, 0, arr.length - 1, new Comparable[4]);

        printArray(arr);
    }

    @Data
    @AllArgsConstructor
    private static class Person implements Comparable<Person> {
        // 注意,对象之间如果需要进行比较,则必须实现Comparable接口,并重写compareTo方法
        private Integer id;
        private String name;

        @Override
        public int compareTo(Person otherPerson) {
            if (Objects.isNull(this.id) || Objects.isNull(otherPerson) || Objects.isNull(otherPerson.getId())) {
                return -1;
            }

            return this.id.compareTo(otherPerson.getId());
        }
    }

    /**
     * 工具方法,用于打印数组
     */
    private void printArray(Comparable[] arr) {
        if (Objects.isNull(arr) || arr.length == 0) {
            return;
        }

        for (Comparable comparable : arr) {
            System.out.println(comparable);
        }
    }

    /**
     * 冒泡排序(排序后,id从小到大)
     *
     * @param arr 待排序的对象数组
     */
    public void bubbleSort(Comparable[] arr) {
        if (Objects.isNull(arr) || arr.length == 0) {
            return;
        }

        int length = arr.length;
        for (int i = 0; i < length; i++) {
            for (int j = i + 1; j < length; j++) {
                if (arr[i].compareTo(arr[j]) > 0) {
                    Comparable tmp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = tmp;
                }
            }
        }
    }

    /**
     * 选择排序(排序后,id从小到大)
     *
     * @param arr 待排序数组
     */
    public void selectSort(Comparable[] arr) {
        if (Objects.isNull(arr) || arr.length == 0) {
            return;
        }

        int length = arr.length;
        for (int i = 0; i < length; i++) {
            int min = i; // min记录本轮最小值的下标
            for (int j = i + 1; j < length; j++) {
                if (arr[min].compareTo(arr[j]) > 0) {
                    min = j; // 发现更小的元素,则将min改为更小元素的下标
                }
            }

            if (i != min) {
                Comparable tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;
            }
        }
    }

    /**
     * 插入排序(排序后,id从小到大)
     *
     * @param arr 待排序数组
     */
    public void insertSort(Comparable[] arr) {
        if (Objects.isNull(arr) || arr.length == 0) {
            return;
        }

        int length = arr.length;
        for (int i = 1; i < length; i++) {
            // 当前所指向的元素比他前面一个元素要小,需调整次序
            if (arr[i].compareTo(arr[i - 1]) < 0) {
                Comparable tmp = arr[i]; // 记录要插入的元素

                int j; // j指向当前元素应该插入的位置
                // 从i往前倒推,找到tmp应该插入的位置(不断将前面比tmp大的元素往后移)
                for (j = i; j > 0 && tmp.compareTo(arr[j - 1]) < 0; j--) {
                    arr[j] = arr[j - 1];
                }

                arr[j] = tmp;
            }
        }
    }

    /**
     * 希尔排序(排序后,id从小到大)
     *
     * @param arr     待排序的数组
     * @param gapList 希尔排序每轮插入排序的增量(小于n的数)
     */
    public void shellSort(Comparable[] arr, int[] gapList) {
        if (Objects.isNull(arr) || arr.length == 0) {
            return;
        }

        if (Objects.isNull(gapList) || gapList.length == 0) {
            // 没有指定增量时,希尔排序就是插入排序,调用前面的插入排序即可
            insertSort(arr);
            return;
        }

        // 指定了增量,插入排序的变形
        int gapNum = gapList.length;
        int arrLength = arr.length;
        for (int i = 0; i < gapNum; i++) {
            int gap = gapList[i]; // 获取本轮的增量
            for (int j = gap; j < arrLength; j++) {
                if (arr[j].compareTo(arr[j - gap]) < 0) {
                    Comparable tmp = arr[j];
                    int k;
                    for (k = j; k > 0 && tmp.compareTo(arr[k - 1]) < 0; k -= gap) {
                        arr[k] = arr[k - gap];
                    }

                    arr[k] = tmp;
                }
            }
        }
    }

    /**
     * 快速排序(排序后,id从小到大)
     *
     * @param arr  待排序数组
     * @param low  需要排序的区间低位(排序在low ~ hight进行,index从0开始)
     * @param high 需要排序的区间高位(排序在low ~ hight进行, index从0开始)
     */
    public void quickSort(Comparable[] arr, int low, int high) {
        if (Objects.isNull(arr) || arr.length == 0 || high <= low) {
            return;
        }

        Comparable tmp = arr[low];// tmp表示本次比较的枢纽元素
        while (low < high) {
            // 从右向左搜索比枢纽元素要小的元素
            while (low < high && arr[high].compareTo(tmp) >= 0) {
                --high;
            }
            // 在枢纽元素的右边遇到了比枢纽元素要小的元素,则进行交换(即使low和high指向一处)
            arr[low] = arr[high];

            // 从左向有搜索比枢纽元素要大的元素
            while (low < high && arr[low].compareTo(tmp) <= 0) {
                ++low;
            }
            // 在枢纽元素的左边遇到了比枢纽元素要大的元素,则进行交换(即使low和high指向一处)
            arr[high] = arr[low];
        }
        // 将枢纽元素放入(此时low和high相同)
        arr[low] = tmp;

        // 递归分别排序左右两部分
        quickSort(arr, 0, low);
        quickSort(arr, low + 1, high);
    }

    /**
     * 归并排序(排序的最终结果在result数组中)
     *
     * @param arr     待排序的数组
     * @param start   待排序部分的低位下标
     * @param end     待排序不分的高位下标
     * @param helpArr 辅助数组
     */
    public void mergeSort(Comparable[] arr, int start, int end, Comparable[] helpArr) {
        if (Objects.isNull(arr) || arr.length == 0 || end <= start) {
            return;
        }

        int mid = (start + end) / 2;

        // 排序左边部分
        int start1 = start;
        int end1 = mid;
        mergeSort(arr, start1, end1, helpArr);

        // 排序右边部分
        int start2 = mid + 1;
        int end2 = end;
        mergeSort(arr, start2, end2, helpArr);

        // 合并左右两部分
        int mergeIndex = start;
        while (start1 <= end1 && start2 <= end2) {
            if (arr[start1].compareTo(arr[start2]) <= 0) {
                helpArr[mergeIndex++] = arr[start1++];
            } else {
                helpArr[mergeIndex++] = arr[start2++];
            }
        }
        while (start1 <= end1) {
            helpArr[mergeIndex++] = arr[start1++];
        }
        while (start2 <= end2) {
            helpArr[mergeIndex++] = arr[start2++];
        }

        // 将辅助数组中的元素拷贝到原数组中
        for (int i = start; i <= end; i++) {
            arr[i] = helpArr[i];
        }
    }
}

  

  

posted @ 2018-08-27 12:48  寻觅beyond  阅读(364)  评论(0)    收藏  举报
返回顶部