排序算法总结

1. 冒泡排序

// 朴素冒泡
void bubble_sort_1(int n) {
    // 总共需要排序 n-1轮
    for(int i=n-1; i>=1; i--) {
        for(int j=0; j<i; j++) {
            if(s[j] > s[j+1])
                swap(s[j], s[j+1]);
        }
    }
}

// 带优化的冒泡
void bubble_sort_2(int n) {
    for(int i=n-1; i>=1; i--) {
        // 标记是否有序
        bool f = false;
        for(int j=0; j<i; j++) {
            if(s[j] > s[j+1])
                swap(s[j], s[j+1]), f=true;
        }
        // 说明没有发生交换
        if(!f) break;
    }
}

2. 快速排序

void quick_sort(int l, int r) {
    if(l >= r)
        return ;
    int i=l, j=r;
    int num = s[l];
    while(i < j) {
        // 从右面找比num小的
        while(i < j && s[j] > num) j--;
        // 从左面找比num大的
        while(i < j && s[i] < num) i++;
        // 交换
        if(i < j)
            swap(s[i], s[j]);
    }
    quick_sort(l, j-1);
    quick_sort(j+1, r);
}

3. 插入排序

void insert_sort(int n) {
    // s[0]已经排序排好了
    for(int i=1; i<=n-1; i++) {
        int j = i-1;
        // j+1 即为要插的位置
        while(j >= 0 && s[j] > s[i])
            j--;
        int tmp = s[i];
        for(int k=i-1; k>=j+1; k--)
            s[k+1] = s[k];
        s[j+1] = tmp;
    }
    return ;
}

// 代码优化版本
void insert_sort(int n) {
    // s[0]已经排序排好了
    for(int i=1; i<=n-1; i++) {
        int j = i-1;
        // j+1 即为要插的位置
        int tmp = s[i];
        while(j >= 0 && s[j] > tmp) {
            s[j+1] = s[j];
            j--;
        }
        s[j+1] = tmp;
    }
    return ;
}

4. 希尔排序

void shell_sort(int n) {
    for(int gap = (n>>1); gap; gap>>=1) {
        // 共分gap个组
        for(int i=0; i<gap; i++) {
            for(int j=i+gap; j<n; j+=gap) {
                int k = j - gap;
                int tmp = s[j];
                while(k >= i && s[k] > tmp) {
                    s[k+gap] = s[k];
                    k-=gap;
                }
                s[k+gap] = tmp;
            }
        }
    }
}

5. 选择排序

void select_sort(int n) {
    // 共n-1轮次
    for(int i=0; i<n; i++) {
        int mn_pos = i;
        for(int j=i+1; j<n; j++) {
            if(s[j] < s[mn_pos]) {
                mn_pos = j;
            }
        }
        if(i != mn_pos)
            swap(s[mn_pos], s[i]);
    }
    return ;
}

6. 堆排序

这里比较trick的点就是,就是比如小根堆,根节点是最小的,因此呢,在排序的时候,s[0]和s[n]交换一下,排序结果就是从大到小的。
想要从小到大的排序结果,需要用大根堆。

// 对堆从st调整, 数组元素为n
void heap_down(int st, int n) {
    int c = st;
    // 有左儿子
    while(2*c+1 <= n) {
        int l = 2*c+1;
        int mn = c;
        if(s[mn] > s[l])
            mn = l;
        if(l+1 <= n && s[mn] > s[l+1])
            mn = l+1;
        if(mn == c)
            break;
        swap(s[c], s[mn]);
        c = mn;
    }
    return ;
}

void heap_sort(int n) {
    for(int i=n/2; i>=0; i--)
        heap_down(i,n);
    for(int i=n; i>0; i--) {
        swap(s[i], s[0]);
        heap_down(0, i-1);
    }
    return ;
}

7. 归并排序

void merge_sort(int l,int r) {
    if(l >= r)
        return ;
    int mid = (l+r)/2;
    merge_sort(l, mid);
    merge_sort(mid+1, r);
    int l1=l, l2=mid+1;
    int k = l;
    while(l1 <= mid && l2 <= r) {
        if(s[l1] > s[l2])
            t[k++] = s[l2++];
        else
            t[k++] = s[l1++];
    }
    while(l1 <= mid)
        t[k++] = s[l1++];
    while(l2 <= r)
        t[k++] = s[l2++];
    for(int i=l; i<=r; i++)
        s[i] = t[i];
    return ;
}

8. 分桶排序

void bubble_sort(int n) {
    for(int i=0; i<n; i++) {
        t[s[i]]++;
    }
    int k = 0;
    for(int i=0; i<N; i++) {
        while(t[i]) {
            s[k++] = i;
            t[i]--;
        }
    }
    return ;
}

9. 基数排序

int get_max(int n) {
    int mx = INT_MIN;
    for(int i=0; i<n; i++) {
        mx = max(mx, s[i]);
    }
    return mx;
}
// 对数组按照"某个位数"进行排序(桶排序)
void count_sort(int n,int exp) {
    int output[n+5];
    int bucket[10]={0};
    for(int i=0; i<n; i++)
        bucket[ (s[i]/exp)%10] ++;
    // bucket[i] 现在存.. 当前位数为i的最后一个位置
    for(int i=1; i<10; i++)
        bucket[i] += bucket[i-1];
    // 从后面开始排是因为,每个在后面的数, 总有比他小的,所以在后面的先排
    for(int i=n-1; i>=0; i--) {
        output[bucket[(s[i]/exp)%10]-1] = s[i];
        bucket[(s[i]/exp)%10]--;
    }
    for(int i=0; i<n; i++)
        s[i] = output[i];
}

void radix_sort(int n) {
    int mx = get_max(n);
    for(int exp=1; mx /exp > 0; exp *= 10) {
        count_sort(n,exp);
    }
}

参考文章

数据结构解析

posted @ 2019-02-11 12:21  Draymonder  阅读(195)  评论(0编辑  收藏  举报