• 八种排序算法


    https://juejin.im/post/5b95da8a5188255c775d8124#heading-4

    1. 冒泡排序Bubble Sort

    每次冒出一个最大的到最后一位

    public void bbsort(int[] arr){
        int le = arr.length;
        for(int i = 0; i < le - 1; i++){
            for(int j = 0; j < le - i - 1; j++){
                if(arr[j] > arr[j+1]) swap(arr, j, j+1);
                }
            }            
    }
    public void swapbycount(int[] arr, int a, int b){
        arr[a] = arr[a] + arr[b];
        arr[b] = arr[a] - arr[b];
        arr[a] = arr[a] - arr[b];
    }

    还可以byBit

    public static void  swapByBitOperation(int[] array, int i, int j) {
            array[i] = array[i]^array[j];
            array[j] = array[i]^array[j]; //array[i]^array[j]^array[j]=array[i]
            array[i] = array[i]^array[j]; //array[i]^array[j]^array[i]=array[j]
        }
    
    作者:foofoo
    链接:https://juejin.im/post/5b95da8a5188255c775d8124
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    2. 快速排序 quick sort

     https://www.geeksforgeeks.org/quick-sort/

     每次把最右边作为pivot,然后把比pivot小的数放在左边,大的放在右边,这样pivot就放在了应该放的位置。

    快速排序也用到了分治法,每次都是先得到pivot应该在的位置,然后sort(arr, left, pivot-1), sort(arr, pivot+1, right)

    partition是来求pivot的位置,partition(int arr[ ], int low, int high)

    从循环从low到high - 1,有两个指针i和j,i 指向smaller element,初始化是i = low - 1,, j = low表示当前element

    如果小于pivot,就i++,然后swap i 和 j的element

    最终pivot 和arr[i + 1]互换,返回i+1

        /* This function takes last element as pivot, 
           places the pivot element at its correct 
           position in sorted array, and places all 
           smaller (smaller than pivot) to left of 
           pivot and all greater elements to right 
           of pivot */
        int partition(int arr[], int low, int high) 
        { 
            int pivot = arr[high];  
            int i = (low-1); // index of smaller element 
            for (int j=low; j<high; j++) 
            { 
                // If current element is smaller than the pivot 
                if (arr[j] < pivot) 
                { 
                    i++; 
      
                    // swap arr[i] and arr[j] 
                    int temp = arr[i]; 
                    arr[i] = arr[j]; 
                    arr[j] = temp; 
                } 
            } 
      
            // swap arr[i+1] and arr[high] (or pivot) 
            int temp = arr[i+1]; 
            arr[i+1] = arr[high]; 
            arr[high] = temp; 
      
            return i+1; 
        } 
      
      
        /* The main function that implements QuickSort() 
          arr[] --> Array to be sorted, 
          low  --> Starting index, 
          high  --> Ending index */
        void sort(int arr[], int low, int high) 
        { 
            if (low < high) 
            { 
                /* pi is partitioning index, arr[pi] is  
                  now at right place */
                int pi = partition(arr, low, high); 
      
                // Recursively sort elements before 
                // partition and after partition 
                sort(arr, low, pi-1); 
                sort(arr, pi+1, high); 
            } 
        } 
      

    3. 插入排序 insertion sort

    从第二个数开始,每次把当前的数放在合适的位置(通过和前面的数比较)

    public void insertionSort(int[ ] arr){
        int le = arr.length;
        for(int i = 1; i < le; i++){
            int j = i-1;
            int tmp = arr[i];
            while(j >= 0 && arr[i] < arr[j]){
                         a[j+1] = a[j];
            j--;
            }
            a[j+1] = tmp;
        }        
    }

    4. 希尔排序ShellSort

    改进版的插入排序

    每次用gap来对数组分组,在组内进行插入排序,gap by default == n / 2, 当gap == 1时排序完成就结束了

    https://www.geeksforgeeks.org/shellsort/

    int sort(int arr[]) 
        { 
            int n = arr.length; 
      
            // Start with a big gap, then reduce the gap 
            for (int gap = n/2; gap > 0; gap /= 2) 
            { 
                // Do a gapped insertion sort for this gap size. 
                // The first gap elements a[0..gap-1] are already 
                // in gapped order keep adding one more element 
                // until the entire array is gap sorted 
                for (int i = gap; i < n; i += 1) 
                { 
                    // add a[i] to the elements that have been gap 
                    // sorted save a[i] in temp and make a hole at 
                    // position i 
                    int temp = arr[i]; 
      
                    // shift earlier gap-sorted elements up until 
                    // the correct location for a[i] is found 
                    int j; 
                    for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) 
                        arr[j] = arr[j - gap]; 
      
                    // put temp (the original a[i]) in its correct 
                    // location 
                    arr[j] = temp; 
                } 
            } 
            return 0; 
        } 

    5. 选择排序 selection sort

    每次把当前数与后面所有的数对比并替换成最小的数

    public class SelectSort {
        public static void sort(int[] arr) {
            for (int i = 0; i < arr.length - 1; i++) {
                int min = i;
                for (int j = i+1; j < arr.length; j ++) { //选出之后待排序中值最小的位置
                    if (arr[j] < arr[min]) {
                        min = j;
                    }
                }
                if (min != i) {
                    arr[min] = arr[i] + arr[min];
                    arr[i] = arr[min] - arr[i];
                    arr[min] = arr[min] - arr[i];
                }
            }
        }

    6. 归并排序 merge sort

    用了divide and conquer分治法的思想,对数组递归调用sort 和 merge

    merge中,先建立两个临时数组分别存放mid左边和mid右边的已经排好的数列,然后合并时,有一方结束就先暂时结束,然后再检查有没有剩下的数加进去就可以了

    public static void sort(int[] arr, int l, int r) {
            if(l < r) {
                int mid = l + (r - l) / 2;
                sort(arr, l, mid);
                sort(arr, mid + 1, r);
                merge(l, r, mid, arr);
            }
        }
        public static void merge(int left, int right, int mid, int[] arr) {
            int n1 = mid - left + 1;
            int n2 = right - mid;
            int[] L = new int[n1];
            int[] R = new int[n2];
    
            for(int i = 0; i < L.length; i++) L[i] = arr[left + i];
            for(int i = 0; i < R.length; i++) R[i] = arr[mid + 1 + i];
            int k = left;
            int i = 0, j = 0;
    
            while(i < n1 && j < n2) {
                if(L[i] <= R[j]){
                    arr[k++] = L[i++];
                }
                else arr[k++] = R[j++];
            }
            while(i < n1) arr[k++] = L[i++];
            while(j < n2) arr[k++] = R[j++];
    
        }

    7. 基数排序

    8. 堆排序 heapsort

    https://blog.csdn.net/qq_42199781/article/details/97134570?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase 图解如何产生大顶堆

    大顶堆:是一个完全二叉树,根的值大于孩子的值,

    public void sort(int arr[]) 
        { 
            int n = arr.length; 
      
            // Build heap (rearrange array) 
            for (int i = n / 2 - 1; i >= 0; i--) 
                heapify(arr, n, i); 
      
            // One by one extract an element from heap 
            for (int i=n-1; i>0; i--) 
            { 
                // Move current root to end 
                int temp = arr[0]; 
                arr[0] = arr[i]; 
                arr[i] = temp; 
      
                // call max heapify on the reduced heap 
                heapify(arr, i, 0); 
            } 
        } 
      
        // To heapify a subtree rooted with node i which is 
        // an index in arr[]. n is size of heap 
        void heapify(int arr[], int n, int i) 
        { 
            int largest = i; // Initialize largest as root 
            int l = 2*i + 1; // left = 2*i + 1 
            int r = 2*i + 2; // right = 2*i + 2 
      
            // If left child is larger than root 
            if (l < n && arr[l] > arr[largest]) 
                largest = l; 
      
            // If right child is larger than largest so far 
            if (r < n && arr[r] > arr[largest]) 
                largest = r; 
      
            // If largest is not root 
            if (largest != i) 
            { 
                int swap = arr[i]; 
                arr[i] = arr[largest]; 
                arr[largest] = swap; 
      
                // Recursively heapify the affected sub-tree 
                heapify(arr, n, largest); 
            } 
        } 
  • 相关阅读:
    这个夏天,感动我的歌,感动我的你
    设计中最困难的部分在于决定要设计什么 设计原本择录
    Sql效能优化总结(续) sql语句优化篇
    sql效能优化总结
    使用AStyle进行代码格式化
    迭代模型 转
    软件项目开发系列开篇杂谈
    Sql效能优化总结(续) 架构调整篇
    throw和throw ex的区别
    面向过程&面向对象 UML&RUP
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13303470.html
Copyright © 2020-2023  润新知