• 一些常见的排序方法


    插入排序: 时间复杂度O(n^2), 辅助存储空间O(1), 稳定排序

    插入排序
    #include <stdio.h>
    #include <stdlib.h>
    
    int A[10000];
    
    void insertsort(int a[], int p, int r) {
        int i, j; 
        for (i = 2; i <= r; ++i) {
            a[0] = a[i]; // 作为元素的备份和起到监视哨的作用 
            for (j = i-1; a[0] < a[j]; --j) { 
                a[j+1] = a[j];
            }
            a[j+1] = a[0];
        }
    }
    
    int main() {
        int N;
        while (1) {
            printf("请输入要排序的元素个数:");
            scanf("%d", &N); 
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &A[i]);
            }
            insertsort(A, 1, N);
            for (int i = 1; i <= N; ++i) {
                printf("%d ", A[i]);    
            }
            puts("");
        }
    }

    快速排序: 时间复杂度O(nlogn), 辅助存储空间O(logn), 非稳定排序

    快速排序
    #include <stdio.h>
    #include <stdlib.h>
    
    int A[10000]; 
    
    int patition(int a[], int p, int r) {
        int i = p-1;
        for (int j = p; j <= r-1; ++j) {
            if (a[j] < a[r]) {
                ++i;
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
        int t = a[i+1];
        a[i+1] = a[r];
        a[r] = t;
        return i+1;
    } 
    
    void quicksort(int a[], int p, int r) {
        if (p < r) {
            int q = patition(a, p, r);
            quicksort(a, p, q-1);
            quicksort(a, q+1, r);
        }
    }
    
    int main() {
        int N;
        while (1) {
            printf("请输入要排序的元素个数:");
            scanf("%d", &N); 
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &A[i]);
            }
            quicksort(A, 1, N);
            for (int i = 1; i <= N; ++i) {
                printf("%d ", A[i]);    
            }
            puts("");
        }
        return 0;    
    }

    树形选择排序: 时间复杂度O(nlogn), 辅助存储空间O(n), 稳定排序

    树形选择排序
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #define INF 0x3f3f3f3f
    
    int N, seq[5000];
    
    int min(int x, int y) {
        return x < y ? x : y;
    }
    
    int modify(int x) {
        int lch = x<<1, rch = x<<1|1;
        if (seq[lch] == INF && seq[rch] == INF) {
            return seq[x] = INF; // 下面已经没有了节点
        }
        if (seq[lch] == seq[x]) { // 如果已经输出的节点来自左边的子树
            seq[x] = min(modify(lch), seq[rch]);
        } else {
            seq[x] = min(modify(rch), seq[lch]);
        }
        return seq[x];
    }
    
    int main() {
        while (1) {
            memset(seq, 0x3f, sizeof (seq));
            printf("请输入要排序的元素个数:");
            scanf("%d", &N);
            printf("请输入%d个元素,以空格隔开:\n", N);
            int deep = int (ceil(log2(1.*N))); // deep 表示要到达第deep+1层,才可以容纳下N个元素
            int sta = int (pow(2, deep));
            for (int i = sta, j = 0; j < N; ++i, ++j) {
                scanf("%d", &seq[i]);
            }
            for (int i = sta-1; i >= 1; --i) {
                int lch = i<<1, rch = i<<1|1; // 相当于 lch = i*2, rch = i*2+1 
                seq[i] = min(seq[lch], seq[rch]);
            }
            while (seq[1] != INF) {
                printf("%d ", seq[1]);
                seq[1] = modify(1);
            }
            puts("");
        }
        return 0;    
    }

    堆排序: 时间复杂度O(nlogn), 辅助存储空间O(1), 非稳定排序

    堆排序
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    int N, seq[5000];
    
    void swap(int a, int b) {
        int t = seq[a];
        seq[a] = seq[b];
        seq[b] = t;    
    }
    
    void down(int p) { // down操作是用来完成使得以节点p为根的子树保持堆的性质 
        int lch = p<<1, rch = p<<1|1;
        if (lch <= N && seq[p] > seq[lch]) {
            swap(p, lch);
            down(lch);
        }
        if (rch <= N && seq[p] > seq[rch]) {
            swap(p, rch);
            down(rch);
        }
    }
    
    void build() {
        for (int i = N/2; i >= 1; --i) {
            int lch = i<<1, rch = i<<1|1;
            if (lch <= N && seq[i] > seq[lch]) {
                swap(i, lch);
                down(lch);
            }
            if (rch <= N && seq[i] > seq[rch]) {
                swap(i, rch);
                down(rch);
            }
        }
    }
    
    int main() { 
        while (1) {
            printf("请输入要排序的元素个数:");
            scanf("%d", &N);
            printf("请输入%d个元素,以空格隔开:\n", N);
            for (int i = 1; i <= N; ++i) {
                scanf("%d", seq+i);    
            }
            build();
            while(N) {
                printf("%d ", seq[1]); 
                swap(1, N--); // 将第一个元素与最后一个元素交换,元素个数减1
                down(1);
            }
            puts("");
        }
        return 0;    
    }

    归并排序: 时间复杂度O(nlogn), 辅助存储空间O(n), 稳定排序

    归并排序
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    int N, seq[5000], temp[5000];
    
    void Merge_Sort(int l, int r) {
        if (l >= r) return; // 如果只有一个元素或者没有元素 
        int mid = (l + r) >> 1; // 右移一位相当 (l + r) / 2
        Merge_Sort(l, mid); // 对两个部分进行一个排序 
        Merge_Sort(mid+1, r);
        // 下面的合并操作一般来说是分治方法里面的难点
        int k = 0, i = l, j = mid+1; 
        // k表示将要合并到的数组的下标, i表示左半部分下标, j表示右半部分下标
        while (i <= mid && j <= r) {
            if (seq[i] < seq[j]) {
                temp[k++] = seq[i++];    
            } else {
                temp[k++] = seq[j++];    
            }
        }
        while (i <= mid) temp[k++] = seq[i++];
        while (j <= r) temp[k++] = seq[j++];
        for (i = 0; i < k; ++i) {
            seq[l + i] = temp[i];
        }
    }
    
    int main() {
        while (1) {
            memset(seq, 0x3f, sizeof (seq));
            printf("请输入要排序的元素个数:");
            scanf("%d", &N);
            printf("请输入%d个元素,以空格隔开:\n", N);
            for (int i = 1; i <= N; ++i) {
                scanf("%d", seq+i);    
            }
            Merge_Sort(1, N);
            for (int i = 1; i <= N; ++i) {
                printf("%d ", seq[i]);
            }
        }
        return 0;    
    }

    当然还有冒泡和选择许多... 就写这么几种,够用了.  到最后还是调用的库函数sort.

  • 相关阅读:
    android之PackageManager简单介绍
    西门子PLC学习笔记二-(工作记录)
    node.js第十课(HTTPserver)
    ubuntu ???????????? no permissions 问题解决
    Web API 设计摘要
    公共 DNS server IP 地址
    用Unicode迎接未来
    vs2010公布时去除msvcp100.dll和msvcr100.dll图讲解明
    linux串口驱动分析
    C++ 中dynamic_cast&lt;&gt;的用法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2858390.html
Copyright © 2020-2023  润新知