八种排序算法

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); 
        } 
    } 
原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13303470.html