啊哈算法 第1章:排序

一、桶排序

  • 优点:快
    时间复杂度:O(M+N)(M:桶的个数,N:待排序的数的个数)
  • 缺点:浪费空间
  • 思路:申请一个大小为n的数组(n为待排序数中的最大数)作为“桶”,“桶的个数”初始化为0,依次输入待排序数并使对应的“桶的个数”增加,最后一次输出相应“个数”的每个“桶”的值。
#include 
using namespace std;
//输入n个0~1000之间的整数,排序
int main()
{
    int n, k, a[10001]={0};
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> k;
        a[k]++;
    }
    //从小到大
    for(int i=0; i<=1000; i++)
        for(int j=0; j<a[i]; j++)
            cout << i << ' ';
    cout << endl;
    //从大到小
    for(int i=1000; i>=0; i--)
        for(int j=0; j<a[i]; j++)
            cout << i << ' ';
    return 0;
}

二、冒泡排序

  • 缺点:时间复杂度:O(N²)
  • 思路:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来(核心部分:双重循环嵌套)
#include 
using namespace std;
//输入n个0~1000之间的整数,排序
int main()
{
    int n, a[1005];
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> a[i];
    //核心部分
    for(int i=0; i<n-1; i++)
    {
        for(int j=0; j<n-1-i; j++)
        {
            if(a[j]>a[j+1])//从小到大
            {
                int t=a[j+1]; a[j+1]=a[j]; a[j]=t;
            }
        }
    }
    for(int i=0; i<n; i++)
        cout << a[i] << ' ';
    return 0;
}

  • 书中提出,冒泡排序法可以对小数排序,还可以对应复杂一些的情况:
    如本题:有5个人的名字和分数,huhu 5分、haha 3分、xixi 5分、hengheng 2分、gaoshou 8分,按照分数由高到低,输出他们的名字和分数
    由于我没有掌握好结构体,所以在这里把代码放一下。
#include 
using namespace std;
struct student
{
    char name[20];
    int score;
};
int main()
{
    struct student a[1000], t;
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> a[i].name >> a[i].score;
    for(int i=0; i<n-1; i++)
    {
        for(int j=0; j<n-1-i; j++)
        {
            if(a[j].score<a[j+1].score)
            {
                t=a[j+1]; a[j+1]=a[j]; a[j]=t;
            }
        }
    }
    for(int i=0; i<n; i++)
        cout << a[i].name << '\t' << a[i].score << endl;
    return 0;
}

三、快速排序(最常用)

  • 平均时间复杂度:O(NlogN)
    最好的情况:O(NlogN)
    最坏的情况:和冒泡排序相同O(N²)
  • 思路:选取基准数,把比它大和比它小的数分别换到它两边,每一轮皆如此(递归),直到排序完成
  • 思想:二分
  • 快速排序的优化就是中间值的选取问题,故中间值的选取可以写随机数(学长教的啊哒哒)
#include 
using namespace std;
int a[101];
void quicksort(int left, int right)
{
    int i=left, j=right, temp=a[left];
    if(i>j)
        return ;
    while(i!=j)
    {
        //从小到大
        while(a[j]>=temp && j>i)
            j--;
        while(a[i]<=temp && j>i)
            i++;
        //从大到小
        /*while(a[j]<=temp && j>i)
            j--;
        while(a[i]>=temp && j>i)
            i++;*/
        if(i<j)
        {
            int t=a[i]; a[i]=a[j]; a[j]=t;
        }
    }
    a[left]=a[i];
    a[i]=temp;
    quicksort(left, i-1);
    quicksort(i+1, right);
    return ;
}
int main()
{
    int n;
    cin >> n;
    for(int i=1; i<=n; i++)
        cin >> a[i];
    quicksort(1, n);
    for(int i=1; i<=n; i++)
        cout << a[i] << ' ';
    return 0;
}

你可能感兴趣的:(笔记)