Skip to content

Latest commit

 

History

History
 
 

学习笔记

###排序算法总结

/**
 * Description: 冒泡排序
 *
 * 进行n轮交换,每一轮将较大的数跟后面的数交换,直到将最大的数放到数组的末尾
 * 时间复杂度:O(n^2)
 */
public class BubbleSort {

    int[] bubbleSort(int[] arr){

        int len = arr.length;

        for(int i=0;i<len-1;i++){
            for(int j = 0;j<len-1-i;j++){
                if(arr[j] > arr[j+1]){
                    int tmp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = tmp;
                }
            }
        }

        return arr;
    }
}

/**
 * Description: 插入排序
 * 对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
 * 时间复杂度:O(n^2)
 */
public class InsertionSort {

    int[] insertionSort(int[] arr) {

        int len = arr.length;
        int preIndex = 0;
        int cur = 0;

        for (int i = 1; i < len; i++) {
            preIndex = i-1;
            cur = arr[i];
            while(preIndex>=0 && arr[preIndex] > cur){
                arr[preIndex+1] = arr[preIndex];
                preIndex--;
            }
            arr[preIndex+1] = cur;
        }

        return arr;
    }

}


/**
 * Description:计数排序
 * 计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。
 * 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数
 */
public class CountingSort {

    public static void countingSort(int[] arr, int maxValue) {

        int[] bucket = new int[maxValue + 1];

        for (int i = 0; i < arr.length; i++) {
            bucket[arr[i]]++;
        }


        int idx = 0;
        for (int j = 0; j < bucket.length; j++) {
            while (bucket[j] > 0) {
                arr[idx++] = j;
                bucket[j]--;
            }
        }

    }

}


/**
 * Description:快速排序
 * 过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,
 * 则可分别对这两部分记录继续进行排序,以达到整个序列有序。
 */
public class QuickSort {

    public static void quickSort(int[] array, int begin, int end) {
        if (end <= begin) {
            return;
        }
        int pivot = partition(array, begin, end);
        quickSort(array, begin, pivot - 1);
        quickSort(array, pivot + 1, end);
    }

    static int partition(int[] a, int begin, int end) {
        // pivot: 标杆位置,counter: 小于pivot的元素的个数
        int pivot = end, counter = begin;
        for (int i = begin; i < end; i++) {
            if (a[i] < a[pivot]) {
                if (i != counter) {
                    swap(a, counter, i);
                }
                counter++;
            }
        }
        swap(a, pivot, counter);
        return counter;
    }

    private static void swap(int[] arr, int a, int b) {
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }

}

/**
 * Description: 堆排序
 */
public class HeapSort {

    int len;

    void buildMaxHeap(int[] arr) {   // 建立大顶堆
        len = arr.length;
        for (int i = len / 2; i >= 0; i--) {
            heapify(arr, i);
        }
    }

    void heapify(int[] arr, int i) {     // 堆调整
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;

        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }

        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, largest);
        }
    }

    void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    int[] heapSort(int[] arr) {
        buildMaxHeap(arr);
        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, 0, i);
            len--;
            heapify(arr, 0);
        }
        return arr;
    }
}

/**
 * Description: 希尔排序
 *
 * 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。
 * 它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序
 * 希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列
 * 时间复杂度:O(n^1.3)
 */
public class ShellSort {

    int[] shellSort(int[] arr) {

        int len = arr.length;
        for (int gap = len / 2; gap > 0; gap = gap / 2) {
            for (int i = gap; i < len; i++) {
                int j = i;
                int current = arr[i];
                while (j - gap >= 0 && current < arr[j - gap]) {
                    arr[j] = arr[j - gap];
                    j = j - gap;
                }
                arr[j] = current;
            }
        }
        return arr;
    }

}