美文网首页
各种排序算法

各种排序算法

作者: shoulda | 来源:发表于2018-07-15 20:46 被阅读0次

    1.冒泡排序

    1.有多少趟
    2.每趟向前产生一个最大数

    //主要功能函数
    public static void bubbleSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int e = arr.length - 1; e > 0; e--) {
                for (int i = 0; i < e; i++) {
                    if (arr[i] > arr[i + 1]) {
                        swap(arr, i, i + 1);
                    }
                }
            }
        }
    
    //辅助函数
    public static void swap(int[] arr, int i, int j) {
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        }
    

    2.插入排序

    1.顺序遍历每个数字
    2.每遍历一个数字,就向前挨个比较,然后放在合适的位置

    //主要功能函数
    public static void insertionSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int i = 1; i < arr.length; i++) {
                for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
                    swap(arr, j, j + 1);
                }
            }
        }
    //辅助排序
    public static void swap(int[] arr, int i, int j) {
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        }
    

    3.选择排序

    1.从每个节点依次向前遍历一次
    2.在每一次遍历的过程记录下最小的下标

    //主要功能函数
    public static void selectionSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int i = 0; i < arr.length - 1; i++) {
                int minIndex = i;
                for (int j = i + 1; j < arr.length; j++) {
                    minIndex = arr[j] < arr[minIndex] ? j : minIndex;
                }
                swap(arr, i, minIndex);
            }
        }
    
    //辅助函数
    public static void swap(int[] arr, int i, int j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    

    4.堆排序

    1.先遍历数组元素,构建最大堆
    2.每次构建最大堆后,将堆顶元素和数组末尾元素进行互换。
    3.接着在进行最大堆的构建

    //第一次构建最大堆
    public static void heapSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int i = 0; i < arr.length; i++) {
                heapInsert(arr, i);
            }
            int size = arr.length;
            swap(arr, 0, --size);
            while (size > 0) {
                heapify(arr, 0, size);
                swap(arr, 0, --size);
            }
        }
    //插入
    public static void heapInsert(int[] arr, int index) {
            while (arr[index] > arr[(index - 1) / 2]) {
                swap(arr, index, (index - 1) / 2);
                index = (index - 1) / 2;
            }
        }
    //整理堆
    public static void heapify(int[] arr, int index, int size) {
            int left = index * 2 + 1;
            while (left < size) {
                int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
                largest = arr[largest] > arr[index] ? largest : index;
                if (largest == index) {
                    break;
                }
                swap(arr, largest, index);
                index = largest;
                left = index * 2 + 1;
            }
        }
    //交换
    public static void swap(int[] arr, int i, int j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    

    5.归并排序

    1.总体思想是利用递归
    2.先分成两边子问题,并利用递归函数,把左右两边都排好序。
    3.在合并
    原理:利用栈

    //主要
    public static void mergeSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            mergeSort(arr, 0, arr.length - 1);
        }
    
    //主要方法
    public static void mergeSort(int[] arr, int l, int r) {
            if (l == r) {
                return;
            }
            int mid = l + ((r - l) >> 1);
            mergeSort(arr, l, mid);
            mergeSort(arr, mid + 1, r);
            merge(arr, l, mid, r);
        }
    
    public static void merge(int[] arr, int l, int m, int r) {
                   //借助一个辅助函数
            int[] help = new int[r - l + 1];
            int i = 0;
            int p1 = l;
            int p2 = m + 1;
            while (p1 <= m && p2 <= r) {
                help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
            }
            while (p1 <= m) {
                help[i++] = arr[p1++];
            }
            while (p2 <= r) {
                help[i++] = arr[p2++];
            }
            for (i = 0; i < help.length; i++) {
                arr[l + i] = help[i];
            }
        }
    

    6.快速排序

    1.经典快速排序,以最后一个数字为标准,然后小于这个数字的放在数组左边,大于这个数的放在数组右边。
    2.标记两个量,less = l - 1,more = r;

    public static void quickSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            quickSort(arr, 0, arr.length - 1);
        }
    
    public static void quickSort(int[] arr, int l, int r) {
            if (l < r) {
                swap(arr, l + (int) (Math.random() * (r - l + 1)), r);  
                int[] p = partition(arr, l, r);
                quickSort(arr, l, p[0] - 1);
                quickSort(arr, p[1] + 1, r);
            }
        }
    
    //partition过程
    public static int[] partition(int[] arr, int l, int r) {
            int less = l - 1;
            int more = r;
            while (l < more) {
                if (arr[l] < arr[r]) {
                    swap(arr, ++less, l++);
                } else if (arr[l] > arr[r]) {
                    swap(arr, --more, l);
                } else {
                    l++;
                }
            }
            swap(arr, more, r);
            return new int[] { less + 1, more };
        }
    
    插入,选择,冒泡: 时间复杂度O(N2)  额外空间复杂度O(1)
    堆排序,归并排序,快速排序:O(NlogN)  额外空间复杂度 O(1) O(N) O(logN)
    

    相关文章

      网友评论

          本文标题:各种排序算法

          本文链接:https://www.haomeiwen.com/subject/kmyppftx.html