十大经典排序算法(图解、算法实现)

一个排序算法可视化的,很魔性,很好用。

链接:https://pan.baidu.com/s/1hCoMku7UL7IN4hIdYTsuJg  提取码:4y4v 


 

  1.冒泡排序 

void bubbleSort(int *a, int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            if (a[j - 1] > a[j])
                swap(a[j - 1], a[j]);
        }
    }
}
View Code

  2.选择排序

void selectSort(int *a, int length) {
    for (int i = 0; i < length; i ++) {
        int minIndex = i;
        for (int j = i + 1; j < length; j++) {
            minIndex = a[j] < a[minIndex] ? j : minIndex;
        }
        swap(a[i], a[minIndex]);
    }
}
View Code

  3.插入排序

插入排序在数组近乎于有序的时候,比O(nlogn)的排序是还要快。

void insertSort(int *a, int length) {
    for (int i = 1; i < length; i++) {
        int j, temp = a[i];
        for (j = i; temp < a[j-1] && j>0; j--) {
            a[j] = a[j-1];
        }
        a[j] = temp;
    }
}
View Code

  4.希尔排序(特殊插入排序)

  该方法的基本思想是:

  • 选择一个t,得到一个间隔序列t,t/2,t/4,…,1
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为length/t(可能少一个)的子序列,分别对各子表进行直接插入排序。

间隔序列的取法有各种方案。最初shell提出取t/2向下取整,直到t=1。但由于直到最后一步,在奇数位置的元素才会与偶数位置的元素进行比较,这样使用这个序列的效率会很低。不同的序列会使希尔排序算法的性能有很大的差异 至今为止还没有一个最完美的增量序列公式,这里选用全为t/2向下取整

  希尔排序必须保证最后一次划分间隔为1,希尔排序又叫缩小增量排序

(这里盗用数据结构书上的图了~,可以说是很形象了,不过图中选取的增量序列是 t-2)

void shellSort(int*data, unsigned int len)
{
    for (int div = len / 2; div >= 1; div = div / 2) {
        for (int i = 0; i < div; ++i) {
            for (int j = i + div; j < len; j += div) {
                int k, temp = data[j];
                for (k = j - div; k >= 0 && temp < data[k]; k -= div) {
                    data[k + div] = data[k];
                }
                data[k + div] = temp;
                /*for (k = j; k >= div && temp < data[k - div]; k -= div) {
                    data[k] = data[k - div];
                }
                data[k] = temp;*/
            }
        }
    }
}

  5. 归并排序

   该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序利用了完全二叉树特性,是一种十分高效的稳定排序。

void meger(int *a, int left, int mid, int right) {
    int *b = new int[right - left + 1];
    int t = 0, i = left, j = mid + 1;

    while (i <= mid && j <= right) { 
        b[t++] = a[i] < a[j] ? a[i++] : a[j++]; 
    }

    while (i <= mid) b[t++] = a[i++];
    while (j <= right) b[t++] = a[j++];

    i = left; t = 0;
    while (i <= right) a[i++] = b[t++];
    delete[]b;
}
void megerSort(int *a, int left, int right) {
    if (left == right) return;
    int mid = (right + left) >> 1;
    megerSort(a, left, mid);
    megerSort(a, mid + 1, right);
    meger(a, left, mid, right);
}

   6.快速排序

  快速排序的思想很简单,就是先确定一个基准 SIGN,左右开工,从两边遍历数组将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

    快速排序选取第一个元素作为基准。这样在数组已经有序的情况下,算法将会降级为O(n^2)。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为基准。

    冯·诺依曼·赵四说过:“快速排序是看脸的,人丑排得慢。” 看来我是排不好了。

void quickSort(int *a, int left,int right) {
    if (left >= right) return;
    int sign = a[left];
    int i= left, j= right;
    while (i < j) {
        while (i<j&&a[j] >= sign)j--;
        while (i<j&&a[i] <= sign)i++;
        swap(a[i],a[j]);
    }
    swap(a[left], a[i]);
    quickSort(a, left, i - 1);
    quickSort(a, i + 1, right);

}

猜你喜欢

转载自www.cnblogs.com/czc1999/p/10266436.html