[算法篇]经典排序算法

以下算法选用的描述语言均为Java语言

1、冒泡排序:

时间复杂度为O(n^2)

一开始交换区间为0~N-1,然后第一个数跟第二个数进行比较,哪个大哪个就放后面。然后是第二个数和三个数比较,哪个大哪个就放后面。依次交换,最终最大的数在最后面。然后把范围从0~N-1到0~N-2。这样第二大的数会放在倒数第二位,依次下去,最终只剩下一个数,冒泡排序完成。

例题:
对于一个int数组,请编写一个冒泡排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

import java.util.*;

public class BubbleSort {
    public int[] bubbleSort(int[] A, int n) {
        // write code here
        for(int i = 0 ; i < n - 1; i++){
            for(int j = 0 ; j < n - 1 - i ; j++){
                if(A[j] > A[j+1]){
                    int temp = A[j+1];
                    A[j+1] = A[j];
                    A[j] = temp;
                }
            }

        }
        return A;
    }
}

2、选择排序:

时间复杂度为O(n^2)

在范围0~N-1上选出一个最小值,把它放到位置0上,然后在1~N-1的范围上选出最小值,把它放到位置1上。依次下去,最后只包含一个数的时候选择排序完成。

对于一个int数组,请编写一个选择排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]

import java.util.*;

public class SelectionSort {
    public int[] selectionSort(int[] A, int n) {
        for (int i = 0; i < n - 1; i++)//控制趟数
        {
            int min = A[i];//始终默认最大的一个数在末尾
            for (int j = i + 1; j < n; j++)
            {
                if(A[j] < min)
                {
                    min = A[j];
                    int temp;
                    temp = A[i];
                    A[i] = A[j];
                    A[j] = temp;
                }
            }
        }
        return A;    
    }
}

3、插入排序:

时间复杂度为O(n^2)

位置0上的数和位置1上的数进行比较,如果位置1上的数更小,就和位置0上的数交换。位置2上的数依次和位置0、位置1上的数交换,如果比位置1小,和位置1交换,继续和位置0比较,如果更小,和位置0交换,依次下去,一直到N-1,自此插入排序完成。

import java.util.*;

public class InsertionSort {
    public int[] insertionSort(int[] A, int n) {
        // write code here
        int exchange;
        int tmp;
        for(int i=1;i<n;i++){
            exchange=i;
            for(int j=i-1;j>=0;j--){
                if(A[j]<=A[exchange])
                    break;
                else{
                    tmp=A[exchange];
                    A[exchange]=A[j];
                    A[j]=tmp;
                    exchange=j;
                }
            }
        }
        return A;
    }
}

4、归并排序

时间复杂度:O(N*logN)

import java.util.*;

public class MergeSort {
    public int[] mergeSort(int[] A, int n) {
        // write code here

        int[] temp = new int[n];
        mergeSortRecurrence(A, 0, n - 1, temp);

        return A;
    }

    public void mergeSortRecurrence(int[] A, int left, int right, int[] temp){
        if(left < right){
            int mid = (left + right) / 2;
            mergeSortRecurrence(A, left, mid, temp);
            mergeSortRecurrence(A, mid + 1, right, temp);
            mergeArrays(A, left, mid, right, temp);
        }
    }

    public void mergeArrays(int[] A, int left, int mid, int right, int[] temp){

        int i = left;
        int j = mid + 1;
        int k = 0;

        while (i <= mid && j <= right) {
            if(A[i] <= A[j]){
                temp[k++] = A[i++];
            }else {
                temp[k++] = A[j++];
            }
        }

        while (i <= mid) {
            temp[k++] = A[i++];
        }

        while (j <= right) {
            temp[k++] = A[j++];
        }

        for (i = 0; i < k; i++) {
            A[left + i] = temp[i];
        }

    }
}

让数组中的每一个数单独成为长度为1的有序区间,然后把相邻的长度为1的有序区间之间进行合并,得到最大长度为2的有序区间。然后再把相邻有限区间进行合并,得到最大长度为4的有序区间。依次下去,直到让数组中所有的数合并成一个有序区间,归并排序结束。

5、快速排序

时间复杂度:O(N*logN)

快速排序是随机的在数组中选择一个数,小于等于这个数的统一放在这个数的左边,大于这个数的统一放在这个数的右边。接下来对左右两个部分分别进行递归的调用快速排序的过程,这样使得整个数组都有序了。

import java.util.*;

public class QuickSort {
    public int[] quickSort(int[] A, int n) {
        // write code here
       process(A,0,n-1);
        return A;
    }
    private void process(int[] aar,int left,int right){
        if(left<right){


        int mun=aar[left];
        int l=left,r=right;
        while(l<r){
           while(aar[r]>=mun&&r>l)
               r--;
            if(l<r){
                int a=aar[r];
                aar[r]=mun;
                aar[l]=a;
                l++;
            }

            while(aar[l]<mun&&l<r){
                l++;
            }
            if(l<r){
                 int a=aar[l];
                aar[l]=mun;
                aar[r]=a;
               // r--;
            }
        }
            //aar[l]=mun;
        process(aar,left,l-1);
        process(aar,r+1,right);

        }

    }
}

6、堆排序
时间复杂度:O(N*logN)

把数组中的N个数建成大小为N的大根堆。堆顶元素为最大值,把堆顶元素与堆的最后一个元素互换,然后把最大值脱离出整个结构,放在数组的最后的位置。然后再把N-1大小的堆从堆顶开始进行调整。在调整出一个N-1的数的最大值放在堆顶定位位置。接下来把堆顶的位置和整个堆的最后一个位置互换,同样作为堆的有序部分。依次继续,堆的大小每次减1,有序部分每次加1。这样,整个数组就变的有序了。

7、希尔排序
时间复杂度:O(N*logN)
关键在于步长的选择:

插入排序的改良,只是步长由大到小依次交换。

你可能感兴趣的:(排序算法)