Contents
一大波数正在靠近——排序
- 简单桶排序,真正的桶排序要比这个复杂一些;
时间复杂度 O(M + N),这是一个非常快的排序算法;
要命的是,它非常浪费空间!
Question:数据范围0~1000,需1001个桶
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int book[1024]; //能装0~1023之间的数的桶
int n,t;
for(int i = 0; i < 1024; i++) {
book[i] = 0; //不给桶初始化的话会出错
}
cout << "请输入待装桶的元素的个数:" << endl;
cin >> n;
cout << "请依次输入数(限制范围:0~1023):" << endl;
for(int i = 1; i <= n; i++) {
cin >> t;
book[t]++; //输入数后,相应编号的桶中计数加一
}
for(int i = 0; i < 1024; i++) {
for(int j = 1; j <= book[i]; j++) { //桶中有几个计数,就输出几次桶编号
printf("%d ", i);
}
} //若j=0的话,错误分析下
getchar();getchar();
system("pause");
return 0;
}
- 冒泡排序
冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来;
核心部分,双重嵌套循环;
时间复杂度 O(N2),这是一个非常高的时间复杂度;
Question:现在分别有5个人的名字和分数:huhu 5分、haha 3分、xixi 5分、hengheng 2分、gaoshou 8分,请按分数从高到低,输出名字
#include<iostream>
using namespace std;
struct student {
char name[21];
int score;
}; //创建一个结构体,用来存储姓名和分数
typedef student Student;
int main()
{
Student a[124],t;
int num;
cout << "the number of students: ";
cin >> num;
for (int i = 0; i < num; i++) {
cout << "name: ";
cin >> a[i].name;
cout << "score: ";
cin >> a[i].score;
}
for (int i = 0; i < num - 1; i++) { //排n - 1遍,最后一遍不用排
for (int j = 0; j < num - i - 1; j++) { //从第一位开始比较直到最后一个尚未归位的数,需要- 1不然会越界(比较时有a[j+1])
if (a[j].score < a[j+1].score) {
t = a[j]; //换的是结构体(包括姓名和分数)
a[j] = a[j+1];
a[j+1] = t;
}
}
}
for(int i = 0; i < num; i++) {
cout << a[i].name << " ";
}
getchar();
getchar(); //用来暂停程序,以便查看程序输出的内容,可用system("pause");等来代替
return 0;
}
可以加一个判断:若已有序,则终止冒泡:
链接:ADT_起泡排序的实现代码.
- 快速排序,
先找一个数为基准数 (我选第一个数),将基准数放在辅助空间里;
然后从右开始找比基准数小的数,标记为 high,找到后将其值赋值给基准数(第一个位置),
再从基准数开始从左往右找一个比基准数大的数,标记为 low,找到后将其值赋值给 high 标记位置;
再从 high 的开始找,找到赋值给 low,然后重复操作直到 low >= high 为止;
将辅助空间的基准数赋值给 low high 交界位置,然后此位置的左右两边重复此操作,直到排序完成;
自己按理解叙述的,并不严谨; - 时间复杂度 最坏为 O( N2);平均时间复杂度为 O( NlogN);
Question:快速排序
链接:快排.