Stl中算法组件是Function template,stl中提供了几十种算法,分为质变算法和非质变算法,主要头文件有
我们先来看下主流的排序算法有哪些?
根据时间复杂度的不同,主流的排序算法可以分为3大类
时间复杂度为O(n^2)的排序算法
冒泡排序
选择排序
插入排序
时间复杂度为O(nlogn)的排序算法
快速排序
归并排序
堆排序
时间复杂度为线性的排序算法
计数排序
桶排序
基数排序
Stl中使用的是时间复杂为O(nlogn)的快速排序、堆排序以及时间复杂度为O(n^2)的插入排序。
由于自己对算法这块基础知识的掌握十分薄弱。趁此机会也把算法来学习下,今天我们就从最基础的冒泡排序开始学起。接下来几篇逐一学习其他几种排序算法,最后分析stl中sort的实现。
stl的排序算法仅适用于普通数组和部分类型的容器( array、vector、deque )
sort() 函数有 2 种用法,其语法格式分别为:
//方法1: 对 [first, last) 区域内的元素做默认的升序排序,其中first 和 last 都为随机访问迭代器
void sort (RandomAccessIterator first, RandomAccessIterator last);
//方法2: 按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序,默认是升序排列,stl中也提供了std::greater降序排列的函数对象
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
下面我们来实践,使用sort进行排序
#include
#include
#include
using namespace std;
//声明一个函数对象,用于sort的cmp
struct myclass{
bool operator()(int x,int y){return x());
printSortArray(myarray,size);
return 0;
}
关注+后台私信我,领取2022最新最全学习提升资料包+面试题+学习视频,内容包括(C/C++,Linux,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)等等
冒泡排序是指:把相邻的元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置;否则 位置保持不变。
冒泡排序每一轮都要遍历所有元素,总共遍历(元素个数-1)轮,每一轮之后保证大的排在后面,时间复杂度是O(n^2)
下面我们来实践,实现冒泡排序
#include
#include
using namespace std;
void printSortArray(int i,int myarray[],int size){
cout<<"loop = " <myarray[j+1]){
tmp = myarray[j];
myarray[j] =myarray[j+1];
myarray[j+1] = tmp;
}
}
printSortArray(i,myarray,size);
}
}
int main(void) {
int myarray[] ={4,3,5,9,2,7,1,8,6};
int size = sizeof(myarray)/sizeof(myarray[0]) ;
cout<<"size="<
输出结果如下:
@"size=9\r\n"
@"loop = 1\r\n"
@"3 4 5 2 7 1 8 6 9 \r\n"
@"loop = 2\r\n"
@"3 4 2 5 1 7 6 8 9 \r\n"
@"loop = 3\r\n"
@"3 2 4 1 5 6 7 8 9 \r\n"
@"loop = 4\r\n"
@"2 3 1 4 5 6 7 8 9 \r\n"
@"loop = 5\r\n"
@"2 1 3 4 5 6 7 8 9 \r\n"
@"loop = 6\r\n"
@"1 2 3 4 5 6 7 8 9 \r\n"
@"loop = 7\r\n"
@"1 2 3 4 5 6 7 8 9 \r\n"
@"loop = 8\r\n"
@"1 2 3 4 5 6 7 8 9 \r\n"
可以看到 对数组进行了升序排序。同时也存在两个可优化点
当遍历第6轮后就已经完成了排序,但是后面依旧进行了多次遍历。
第3轮后 5 6 7 8 9已经是有序排列了,但是还是会执行相邻元素冒泡判断
下面小节我们这两个问题进行优化
当完成排序后,不需要再进行后续几轮的遍历。
已经完成排序的部分,不需要每次遍历时再进行比较
针对第一个问题,我们可以在每轮遍历式看看是否还有发生位置交换,如果没有即认为已经完成排序,后续几轮就可以省略了,为此加一个变量进行区分即可。
针对第二个问题,我们可以记录已经排序的头的位置,没轮遍历时,从开始对比到“有序的头位置”即可。为此也要一个变量来记录“有序的头位置”
下面我们来实践
#include
#include
#include
using namespace std;
void printSortArray(int i,int myarray[],int size){
cout<<"loop = " <myarray[j+1]){
tmp = myarray[j];
myarray[j] =myarray[j+1];
myarray[j+1] = tmp;
hasSwap = true;
//如果当前位置有发生交换,则把交换后的位置记录为有序编辑的开始位置
tmpPos= j+1;
}
}
//把上一次遍历时,有序位置的起点记录,作为下一次遍历的右开边界
sortBorder = tmpPos;
printSortArray(i,myarray,size);
//如果没有排序位置交换,则认为已经完成排序,不用再后续遍历
if(!hasSwap){
break;
}
}
}
int main(void) {
int myarray[] ={3,4,2,1,5,6,7,8,9};
int size = sizeof(myarray)/sizeof(myarray[0]) ;
cout<<"size="<
冒泡排序就到这里,接下来几篇逐一学习其他几种排序算法,最后分析stl中sort的实现。一起来学习成长吧。
了解不同排序算法的时间复杂度
运用stl sort排序
实现冒泡排序,并做出优化。