简单算法---排序

(1)冒泡排序

冒泡排序的本质在于交换,通过交换的方式把当前剩余元素的最大值移动到一侧,剩余元素减少为0时,排序结束。

#include<cstdio>
/**
    冒泡排序
*/
int main(){
    int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
    for (int i = 0; i < 9; i++)    //十个元素,进行n-1趟
    {
        for (int j = 0; j < 10-i-1; j++)
        {
            if (a[j]>a[j+1])
            {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
    for each (int i in a)
    {
        printf("%d ", i);
    }
    return 0;
}

从代码可以看出,整个过程执行n-1趟,每一趟从左到右依次比较相邻的两个数。

(2)简单选择排序

简单选择排序是指,对一个序列a中的元素a[0]~a[n-1],令i从0到n-1枚举,进行n趟操作。每趟选出最小(或最大)的元素,与未排序的第一个元素a[i]交换,进行n趟后,所有的元素都是有序的。

#include<cstdio>
/**
    选择排序
*/
int main(){
    int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
    for (int i = 0; i < 9; i++)         //进行n趟操作
    {
        int k = i;
        for (int j = i; j < 10; j++)    //选出[i,n]中最小的元素,下标为k
        {
            if (a[j]<a[k])
            {
                k = j;
            }
        }
        int temp = a[i];
        a[i] = a[k];
        a[k] = temp;
    }
    for each (int i in a)
    {
        printf("%d ", i);
    }
    return 0;
}

可以看出时间复杂度为O(n²)

(3)直接插入排序

基本思想:视第一个元素已有序,从第二个元素开始插入前面的有序序列中,即进行n-1趟排序。

实现:

    #include<cstdio>
    /**
        插入排序        (最狂的风,最静的海)
    */
    int main(){
        int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
        for (int i = 1; i <= 9; i++)        //进行n-1趟排序
        {
            int temp = a[i], k = i;         //temp临时存放将要插入排序的数,k从i开始往前枚举
            while (k>=1&&temp<a[k-1])
            {
                a[k] = a[k - 1];            //把当前最大元素往后挪一位
                k--;
            }
            a[k] = temp;                    //插入数
        }
        for each (int i in a)
        {
            printf("%d ", i);
        }
        return 0;
    }

时间复杂度:O(n²)

(4)归并排序

归并排序是一种基于“归并”思想的排序方法(听着像是一句废话。。。但想说的是这里是最基本的2-路归并排序)。2-路归并的原理是,将序列两两分组,将序列归并为【n/2】个组,组内单独排序;然后将这些组两两归并,生成【n/4】个组,组内再单独排序;以此类推,直到只剩下一个组为止。时间复杂度为O(nlogn)

  1. 递归实现
#include<cstdio>
const int maxn = 100;
void merge(int A[], int L1, int R1, int L2, int R2){
    int i = L1, j = L2;
    int temp[maxn], index = 0;
    while (i<=R1&&j<=R2)
    {
        if (A[i]<=A[j])
        {
            temp[index++] = A[i++];
        }
        else
        {
            temp[index++] = A[j++];
        }
    }
    while (i <= R1) temp[index++] = A[i++];
    while (j <= R2) temp[index++] = A[j++];
    for (int i = 0; i < index; i++)
    {
        A[L1 + i] = temp[i];    //将合并后的序列赋值回数组A
    }
}
void mergeSort(int A[], int left, int right){
    if (left<right)
    {
        int mid = (left + right) / 2;       //取中点
        mergeSort(A, left, mid);                //递归,将左子区间[left,mid]归并排序
        mergeSort(A, mid + 1, right);           //递归,将右子区间[mid+1,right]归并排序
        merge(A, left, mid, mid + 1, right);        //将左子区间和右子区间合并
    }
}
int main(){
    int A[] = { 66, 12, 33, 57, 64, 27, 18 };
    mergeSort(A, 0, 6);
    for each (int a in A)
    {
        printf("%d ", a);
    }
    return 0;
}

2.非递归实现

这里写代码片

快速排序

#include<cstdio>
#include<cstdlib>
#include<time.h>
int Partition(int A[], int left, int right);
void quickSort(int A[], int left, int right){
    if (left<right)
    {
        int pos = Partition(A, left, right);
        quickSort(A, left, pos - 1);
        quickSort(A, pos+1, right);
    }
}
int Partition(int A[], int left, int right){
    int temp = A[left];
    while (left<right)
    {
        while (left<right&&A[right]>temp)
        {
            right--;
        }
        A[left] = A[right];
        while (left<right&&A[left]<=temp)
        {
            left++;
        }
        A[right] = A[left];
    }
    A[left] = temp;
    return left;
}
int main(){
    srand((unsigned)time(NULL));
    int a[10];
    for (int i = 0; i < 10; i++)
    {
        a[i]=rand() % 101 + 1;
    }
    for each (int i in a)
    {
        printf("%d ", i);
    }
    printf("\n");
    quickSort(a, 0, 9);
    for each (int i in a)
    {
        printf("%d ", i);
    }
}

快排随机法

#include<cstdio>
#include<cstdlib>
#include<time.h>
#include<cmath>
#include<algorithm>
using namespace std;
int Partition1(int n[], int left, int right){

    int p = round(1.0*rand() / RAND_MAX*(right - left) + left);
    swap(n[p], n[left]);
    int temp = n[left];
    while (left<right)
    {
        while (left<right&&n[right]>temp)
        {
            right--;
        }
        n[left] = n[right];
        while (left < right&&n[left] <= temp)
        {
            left++;
        }
        n[right] = n[left];
    }
    n[left] = temp;
    return left;
}
void quickSort(int n[], int left, int right){
    if (left<right)
    {
        int pos = Partition1(n, left, right);
        quickSort(n, left, pos-1);
        quickSort(n, pos + 1, right);
    }
}
int main(){
    srand((unsigned)time(NULL));
    int n[] = { 2, 5, 9, 6, 3, 4, 7 };
    quickSort(n, 0, 6);
    for each (int a in n)
    {
        printf("%d ", a);
    }
    return 0;
}

未完待续。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值