一些常见的排序方法

插入排序: 时间复杂度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.

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