排序算法汇总(附动图+代码)

314 阅读2分钟

排序的算法复杂度

image.png

冒泡排序(Bubble Sort)

冒泡排序 Bubble Sort 一种交换排序,宫的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止.

void bubbleSort() {
    int [] a={2,3,7,9,10,20,1,99,78,65,42,100};
    int t = 0;
    for (int i = 0; i < a.length - 1; i++){
        for (int j = 0; j < a.length - 1 - i; j++){
            if (a[j] > a[j + 1]) {
                t = a[j];
                a[j] = a[j + 1];
                a[j + 1] = t;
            }
        }
    }
    System.out.println(Arrays.toString(a));
}

20201208130756466.gif

选择排序(Selection Sort)

简单选择排序法就是通过 次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第 i 个记录交换之。

3b2fbc4848e6a19856d1ffa4f694b034.gif

void selectionSort(){
    int [] a={2,3,7,9,10,20,1,99,78,65,42,100};
    for (int i = 0; i < a.length; i++) {
        int index = i;
        for (int j = i; j < a.length; j++) {
            if (a[j] < a[index])
                index = j;
        }
        int temp = a[index];
        a[index] = a[i];
        a[i] = temp;
    }
    System.out.println(Arrays.toString(a));
}

插入排序(Insertion Sort)

直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的记录数增的有序袭

c894e22dcc48b03559e3087627e3dbb8.gif

void insertionSort(){
    int [] a={2,3,7,9,10,20,1,99,78,65,42,100};
    for(int i=1;i<a.length;i++) {
        if(a[i]<a[i-1]) {
            int temp=a[i];
            int j;
            for(j=i-1;j>=0&&temp<a[j];j--) {
                a[j + 1] = a[j];
            }
            a[j+1]=temp;
        }
    }
    System.out.println(Arrays.toString(a));
}

希尔排序(Shell Sort)

希尔排序是 L.Shell 1959年提出来的一种排序算法,在这之前排序算法的时间复杂度基本都是 O(n²) 的,希尔排序算法是突破这个时阎复杂度的第一批算法之一。希尔对直接插入排序改进后可以增加效率。采取跳跃分割的策略 :将相距某个‘增量'的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。

int [] a={2,3,7,9,10,20,1,99,78,65,42,100};
int length = a.length;
int step = length / 2;
while (step >= 1){
    for (int i = step; i < length; i++) {
        int val = a[i];
        int j = i - step;
        for (; j >= 0; j -= step){
            if (a[j] > val){
                a[j + step] = a[j];
            }
            else {
                break;
            }
        }
        a[j + step] = val;
    }
    step = step / 2;
}
System.out.println(Arrays.toString(a));

堆排序(Heap Sort)

public class HeapSort {

    /**
     * 排序
     */
    public void heapSort(int[] data){
        int length = data.length;
        if (length <= 1){
            return;
        }
        buildHeap(data);
        while (length > 0){
            swap(data, 0, -- length);
            heapify(data, length, 0);
        }
    }

    /**
     * 建堆
     */
    private void buildHeap(int[] data){
        int length = data.length;
        for (int i = (length - 2) / 2; i >= 0; i --) {
            heapify(data, length, i);
        }
    }

    /**
     * 堆化函数
     */
    private void heapify(int[] data, int size, int i){
        while (true){
            int max = i;
            if ((2 * i + 1) < size && data[i] < data[2 * i + 1]) {
                max = 2 * i + 1;
            }
            if ((2 * i + 2) < size && data[max] < data[2 * i + 2]) {
                max = 2 * i + 2;
            }
            if (max == i){
                break;
            }
            swap(data, i, max);
            i = max;
        }
    }

    /**
     * 交换数组中两个元素
     */
    private void swap(int[] data, int i, int j){
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

归并排序(Merge Sort)

aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDYvMDUvNWNmN2JjNjI3ZDE4YTU2NTU5LmdpZg.gif

public class MergeSort {

    public static void mergeSort(int[] data){
        mergeInternally(data, 0, data.length - 1);
    }

    private static void mergeInternally(int[] data, int p, int r){
        if (p >= r){
            return;
        }
        int q = (p + r) / 2;
        //分治递归
        mergeInternally(data, p, q);
        mergeInternally(data, q + 1, r);
        //结果合并
        merge(data, p, q, r);
    }

    private static void merge(int[] data, int p, int q, int r){
        int[] temp = new int[r - p + 1];
        int k = 0;
        int i = p;
        int j = q + 1;
        //比较并合并
        while (i <= q && j <= r){
            if (data[i] < data[j]){
                temp[k ++] = data[i ++];
            }
            else {
                temp[k ++] = data[j ++];
            }
        }
        //合并可能出现的剩余元素
        int start = i;
        int end = q;
        if (j <= r){
            start = j;
            end = r;
        }
        while (start <= end){
            temp[k ++] = data[start ++];
        }
        //拷贝回原数组
        if (r - p + 1 >= 0) {
            System.arraycopy(temp, 0, data, p, r - p + 1);
        }
    }
}

快速排序(Quick Sort)

20200209124339136.gif

public class QuickSort {
    public static void quickSort(int[] data){
        quickSortInternally(data, 0, data.length - 1);
    }

    private static void quickSortInternally(int[] data, int p, int r){
        if (p >= r){
            return;
        }
        int q = partition(data, p, r);
        quickSortInternally(data, p, q - 1);
        quickSortInternally(data, q + 1, r);
    }

    /**
     * 获取分区点函数
     */
    private static int partition(int [] data, int p, int q){
        int pivot = data[q];
        int i = 0;
        int j = 0;
        while (j < q){
            if (data[j] <= pivot){
                swap(data, i, j);
                i ++;
            }
            j ++;
        }
        swap(data, i, q);
        return i;
    }
    /**
     * 交换数组两个元素
     */
    private static void swap(int[] data, int i, int j){
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

java - 十大排序算法总结——SegmentFault 思否