排序算法的分类
1.插入类
直接插入:拿到一个序列 一个个的往里插(摸牌)
具体做法一般是从后往前枚举已有序部分确定插入位置
int A[maxn],n;//n为元素个数,数组下标1~n
void insertSort (){//假设序列{4,5,2}
for(int i=2;i<=n;i++){
int temp = A[i],j=i;//45有序,现在要排的2记为temp。
if(j>1&&temp<A[j-1]){//temp就是2,一个个与前面的数比较,比2大就把这个数放到现在2的位置
A[j]=A[j-1];
j--
}
A[j]=temp;//最后确定好位置后,再把2的值给当前位置。不然每次比较都交换值太麻烦
}
}
折半插入:有序序列中插入(感觉像二叉排序树)
希尔排序:缩小增量排序
2.交换类
冒泡排序:小的像气泡一样向上浮动
快速排序:每一趟选一个关键字,比他小的放前面,比他大的放后面。多次划分
3.选择类
简单选择排序:从头到尾选一个最小的与第一个交换。
void selectSort() {
for(int i=1;i<=n;i++){
int k=i;
for(int j=1;j<=n;j++){
if(A[j]<A[k]){
k=j;
}
}
int temp =A[i];
A[i] = A[K];
A[K] = temp;
}
}
堆排序: 将序列调整成堆得过程。
堆:首先得是完全二叉树,其次所有根节点的值大于等于他所有左右结点的值(这是大顶堆)
建堆:4321顺序排序。
4.归并类
二路归并排序:
5.基数类
Sort函数的应用
使用时必须加的头文件
#include <algorithm>//algorithm意为"算法",是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模板函数
using namespace std;
sort(首元素地址,尾元素的下一个地址,比较函数);
sort的第三个可选参数compare函数(cmp函数)
1.基本数据类型
不填比较函数,sort(a,a+4); 默认从小到大排序
想要从大到小排序 要声明cmp函数,排序规则
#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp(int a,int b){
return a>b;//理解为a>b时,把a放在b的前面
}
int main(){
int a[]={3,1,4,2};
sort(a,a+4,cmp);
for(int i=0;i<4;i++){
printf("%d",a[i]);
}
return 0;
}
对double型 “%.lf”
对char型 “%c”
2.结构体数组
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
int x,y;
}ssd[10];
bool cmp(node a,node b){
return a.x>b.x;//按x值排序
}
int main(){
ssd[0].x = 2;
ssd[0].y = 1;//{2,1}
ssd[1].x = 1;
ssd[1].y = 3;//{1,3}
ssd[2].x = 3;
ssd[2].y = 1;//{3,1}
sort(ssd,ssd+3,cmp);
for(int i=0;i<3;i++){
printf("%d %d\n",ssd[i].x,ssd[i].y);
}
return 0;
}
x相等时按y的大小从小到大的排序
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
int x,y;
}ssd[10];
bool cmp(node a,node b){
if(a.x!=b.x) return a.x>b.x;//按x值排序
else return a.y<b.y;//x相等时按y的大小从小到大的排序
}
int main(){
ssd[0].x = 2;
ssd[0].y = 1;//{2,1}
ssd[1].x = 2;
ssd[1].y = 3;//{2,3}
ssd[2].x = 3;
ssd[2].y = 1;//{3,1}
sort(ssd,ssd+3,cmp);
for(int i=0;i<3;i++){
printf("%d %d\n",ssd[i].x,ssd[i].y);
}
return 0;
}
将字典序小的排在前面
bool cmp(Stu a,Stu b){
if(a.score!=b.score) return a.score>b.score;
else return strcmp(a.name,b.name)<0;
}
3.STL标准容器的排序(只有vector、string、deque)是可以使用sort的,set和map是用红黑树实现的元素本身有序
vector (增强版数组,可以调大小)
5. 成员函数
c.assign(beg,end)c.assign(n,elem)
将[beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。
c.at(idx)
传回索引idx所指的数据,如果idx越界,抛出out_of_range。
c.back() // 传回最后一个数据,不检查这个数据是否存在。
c.begin() // 传回迭代器中的第一个数据地址。
c.capacity() // 返回容器中数据个数。
c.clear() // 移除容器中所有数据。
c.empty() // 判断容器是否为空。
c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
c.erase(pos) // 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg,end) //删除[beg,end)区间的数据,传回下一个数据的位置。
c.front() // 传回第一个数据。
get_allocator // 使用构造函数返回一个拷贝。
c.insert(pos,elem) // 在pos位置插入一个elem拷贝,传回新数据位置。
c.insert(pos,n,elem) // 在pos位置插入n个elem数据。无返回值。
c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值。
c.max_size() // 返回容器中最大数据的数量。
c.pop_back() // 删除最后一个数据。
c.push_back(elem) // 在尾部加入一个数据。
c.rbegin() // 传回一个逆向队列的第一个数据。
c.rend() // 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) // 重新指定队列的长度。
c.reserve() // 保留适当的容量。
c.size() // 返回容器中实际数据的个数。
c1.swap(c2)
swap(c1,c2) // 将c1和c2元素互换。同上操作。
operator[] // 返回容器中指定位置的一个引用。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main(){
vector<int> vi;
vi.push_back(3);
vi.push_back(1);
vi.push_back(2);
sort(vi.begin(),vi.end(),cmp);
for(int i=0;i<3;i++){
printf("%d",vi[i]);
}
return 0;
}
string
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
//
// bool cmp(int a,int b){
// return a>b;
// }
int main(){
string str[3]={"bb","aaa","ccc"};
sort(str,str+3);
for(int i=0;i<3;i++){
cout<<str[i]<<endl;
}
return 0;
}
注意 cout用的是
#include <iostream>
按字符串长度从小到大
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
bool cmp(string str1,string str2){
return str1.length()<str2.length();//从小到大小于号
}
int main(){
string str[3]={"bb","aaa","c"};
sort(str,str+3,cmp);
for(int i=0;i<3;i++){
cout<<str[i]<<endl;
}
return 0;
}