zoukankan      html  css  js  c++  java
  • 常见排序算法

    冒泡排序

    public class BubbleSort {
    
        public static void sort(int[] array) {
            int len = array.length;
            for (int i = 0; i < len - 1; i++) {
                for (int j = 0; j < len - 1 - i; j++) {
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
        // 改进1
        public static void sort2(int[] array) {
            int len = array.length;
    
            for (int i = 0; i < len - 1; i++) {
                // 有序标记,每一轮的初始是true
                boolean isSorted = true;
                for (int j = 0; j < len - 1 - i; j++) {
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        isSorted = false;
                    }
                }
                if (isSorted) break;
            }
        }
        // 改进2
        public static void sort3(int[] array) {
            int len = array.length;
    
            // 记录最后一次交换的位置
            int lastExchangeIndex = 0;
    
            // 无序数列的边界,每次比较只需要比到这里为止
            int sortBorder = len - 1;
    
            for (int i = 0; i < len - 1; i++) {
                boolean isSorted = true;
                for (int j = 0; j < sortBorder; j++) {
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        isSorted = false;
                        // 把无序数列的边界更新为最后一次交换元素的位置
                        lastExchangeIndex = j;
                    }
                }
                sortBorder = lastExchangeIndex;
                if (isSorted) break;
            }
        }
    
        public static void main(String[] args) {
            int[] array = new int[] { 5, 8, 6, 3, 9, 2, 1, 7 };
            sort(array);
            System.out.println(Arrays.toString(array));
        }
    }
    

    选择排序

    public class SelectSort {
    
        public static void sort(int[] array) {
            int len = array.length;
    
            // 总共要经过 N-1 轮比较
            for (int i = 0; i < len - 1; i++) {
                int minIndex = i;
    
                // 每轮需要比较的次数 N-i
                for (int j = i + 1; j < len; j++) {
                    if (array[minIndex] > array[j]) minIndex = j;
                }
    
                // 将找到的最小值和i位置所在的值进行交换
                if (minIndex != i) {
                    int temp = array[i];
                    array[i] = array[minIndex];
                    array[minIndex] = temp;
                }
            }
    
        }
    
        public static void main(String[] args) {
            int[] array = new int[]{3, 4, 2, 1, 5, 6, 7, 8};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
    
    }
    

    插入排序

    public class InsertSort {
    
        public static void sort(int[] array) {
            int len = array.length;
            // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
            for (int i = 1; i < len; i++) {
                // 记录要插入的数据
                int temp = array[i];
    
                // 从已经排序的序列最右边的开始比较,找到比其小的数
                int j = i;
                while (j >= 1 && array[j - 1] > temp) {
                    array[j] = array[j - 1];
                    j--;
                }
                array[j] = temp;
            }
        }
    
        public static void main(String[] args) {
            int[] array = new int[]{3, 4, 2, 1, 5, 6, 7, 8};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
    }
    

    希尔排序

    public class ShellSort {
    
        public static void sort2(int[] array) {
            int len = array.length;
            for (int step = len / 2; step > 0; step /= 2) {
                for (int i = step; i < len; i++) {
                    int temp = array[i];
                    int j = i - step;
                    while (j >= 0 && array[j] > temp) {
                        array[j + step] = array[j];
                        j -= step;
                    }
                    array[j + step] = temp;
                }
            }
        }
    
        public static void sort(int[] array) {
            int len = array.length;
            // 希尔排序的增量
            int step = len;
            while (step > 1) {
                // 使用希尔增量的方式,即每次折半
                step /= 2;
                for (int x = 0; x < step; x++) {
                    for (int i = x + step; i < len; i += step) {
                        int temp = array[i];
                        int j = i;
                        while (j >= step && array[j - step] > temp) {
                            array[j] = array[j - step];
                            j -= step;
                        }
                        array[j] = temp;
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            int[] array = {5, 3, 9, 12, 6, 1, 7, 2, 4, 11, 8, 10};
            sort2(array);
            System.out.println(Arrays.toString(array));
        }
    
    }
    

    归并排序

    public class MergeSort {
    
        // 划分
        public static void mergeSort(int[] array, int start, int end) {
            if (start == end) return;
            int mid = (start + end) / 2;
            // 折半成两个小集合,分别进行递归
            mergeSort(array, start, mid);
            mergeSort(array, mid + 1, end);
            merge(array, start, mid, end);
        }
    
        // 合并
        private static void merge(int[] array, int start, int mid, int end) {
            // 开辟临时空间
            int len = end - start + 1;
            int[] tempArr = new int[len];
            int p1 = start;
            int p2 = mid + 1;
            int p = 0;
            // 比较两个小集合的元素,依次放入大集合
            while (p1 <= mid && p2 <= end) {
                if (array[p1] <= array[p2]){
                    tempArr[p++] = array[p1++];
                } else {
                    tempArr[p++] = array[p2++];
                }
            }
    
            // 左侧小集合还有剩余,依次放入大集合尾部
            while (p1 <= mid) {
                tempArr[p++] = array[p1++];
            }
            // 右侧小集合还有剩余,依次放入大集合尾部
            while (p2 <= end) {
                tempArr[p++] = array[p2++];
            }
    
            // 把大集合的元素复制回原数组
            /*for (int i = 0; i < len; i++) {
                array[start++] = tempArr[i];
            }*/
    
            System.arraycopy(tempArr, 0, array, start, len);
        }
    
        public static void main(String[] args) {
            int[] array = {5, 8, 6, 3, 9, 2, 1, 7};
            mergeSort(array, 0, array.length - 1);
            System.out.println(Arrays.toString(array));
        }
    
    }
    

    快速排序

    public class QuickSort {
    
        public static void quickSort(int[] array, int startIndex, int endIndex) {
            // 递归结束条件:startIndex大于等于endIndex的时候
            // 当partition为0时,会出现start > end的情况
            if (startIndex >= endIndex) return;
            // 得到基准元素的位置
            int pivotIndex = partition(array, startIndex, endIndex);
            // 用分治法递归数列的两部分
            quickSort(array, startIndex, pivotIndex - 1);
            quickSort(array, pivotIndex + 1, endIndex);
        }
    
        // 栈代替递归
        public static void quickSort2(int[] array, int startIndex, int endIndex) {
            Stack<Map<String, Integer>> stack = new Stack<>();
            HashMap<String, Integer> map = new HashMap<>();
            map.put("start", startIndex);
            map.put("end", endIndex);
            stack.push(map);
    
            while (!stack.empty()) {
                Map<String, Integer> popMap = stack.pop();
                Integer start = popMap.get("start");
                Integer end = popMap.get("end");
                int pivotIndex = partition2(array, start, end);
    
                if (start < pivotIndex - 1) {
                    Map<String, Integer> leftMap = new HashMap<>();
                    leftMap.put("start", start);
                    leftMap.put("end", pivotIndex - 1);
                    stack.push(leftMap);
                }
                if (end > pivotIndex + 1) {
                    Map<String, Integer> rightMap = new HashMap<>();
                    rightMap.put("start", pivotIndex + 1);
                    rightMap.put("end", end);
                    stack.push(rightMap);
                }
            }
        }
    
        // 挖坑法
        private static int partition(int[] array, int startIndex, int endIndex) {
            // 取第一个位置的元素作为基准元素
            int pivot = array[startIndex];
            // 坑的位置,初始等于pivot的位置
            int pIndex = startIndex;
            // 大循环在左右指针重合时结束
            while (startIndex < endIndex) {
                // 从右向左进行比较
                while (array[endIndex] >= pivot && startIndex < endIndex) {
                    endIndex--;
                }
                array[pIndex] = array[endIndex];
                pIndex = endIndex;
    
                // 从左向右进行比较
                while (array[startIndex] < pivot && startIndex < endIndex) {
                    startIndex++;
                }
                array[pIndex] = array[startIndex];
                pIndex = startIndex;
    
            }
            array[pIndex] = pivot;
    
            return pIndex;
        }
    
        // 指针交换法
        private static int partition2(int[] array, int startIndex, int endIndex) {
            // 取第一个位置的元素作为基准元素
            int pivot = array[startIndex];
            int pIndex = startIndex;
            startIndex++;
            // 大循环在左右指针重合时结束
            while (startIndex < endIndex) {
                while (array[endIndex] >= pivot && startIndex < endIndex) {
                    endIndex--;
                }
                while (array[startIndex] < pivot && startIndex < endIndex) {
                    startIndex++;
                }
                if (startIndex < endIndex) {
                    int temp = array[startIndex];
                    array[startIndex] = array[endIndex];
                    array[endIndex] = temp;
                }
            }
            int temp = array[startIndex];
            array[startIndex] = pivot;
            array[pIndex] = temp;
    
            return startIndex;
        }
    
        public static void main(String[] args) {
            int[] arr = new int[] {4,4,7,6,5,3,2,8,1};
            quickSort2(arr, 0, arr.length-1);
            System.out.println(Arrays.toString(arr));
        }
    
    }
    
  • 相关阅读:
    2020.11.9
    2020.11.6
    2020.11.5
    2020.11.2
    建站纪念
    退役记——CCC2020&CCO2020
    BZOJ2809&&LG1552 APIO2012派遣(线段树合并)
    BZOJ4668 冷战(LCT维护最小生成树)
    BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机)
    BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
  • 原文地址:https://www.cnblogs.com/oumae/p/14470237.html
Copyright © 2011-2022 走看看