一.快速排序

#include<iostream>
#include<algorithm>//排序函数全部包含在这个头文件里面
using namespace std;
int main()
{
	int n,a[100],i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);

	sort(a,a+n);//从小到大 

	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");

	sort(a,a+n,greater<int>());//从大到小 

	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");

	stable_sort(a,a+n);//稳定排序,从小到大 

	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");

	stable_sort(a,a+n,greater<int>());//稳定排序,从大到小 

	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");

	return 0;
}

这些都是比较常见地排序方法,排序原理比较复杂

(emmm,其实是我不能理解,所以才没有进行解释,但是这个会用就好了,如果可以最好去查一下快排的实现原理)


二.二分查找

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n,a[100],x,i,t;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	scanf("%d",&x);
	
	sort(a,a+n);//从小到大排序
	
	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");
	
	t=lower_bound(a,a+n,x)-a;//从头开始二分查找,返回找到的第一个大于或等于要找数据的地址,如果没有找到,返回最后一个数据以后的一个地址(无意义) 
	if(t==n)t--;//如果未找到,t=n,向前推一位才有对应的数据 
	printf("%d\n",a[t]);
	
	t=upper_bound(a,a+n,x)-a;//从头开始二分查找,返回找到的第一个大于要找数据的地址,如果没有找到,返回最后一个数据以后的一个地址(无意义)
	if(t==n)t--;//如果未找到,t=n,向前推一位才有对应的数据 
	printf("%d\n",a[t]);
	
	sort(a,a+n,greater<int>());//从大到小排序
	
	for(i=0;i<n;i++)
	printf("%4d",a[i]);
	printf("\n");
	
	t=lower_bound(a,a+n,x,greater<int>())-a;//从头开始二分查找,返回找到的第一个小于于或等于要找数据的地址,如果没有找到,返回最后一个数据以后的一个地址(无意义) 
	if(t==n)t--;//如果未找到,t=n,向前推一位才有对应的数据 
	printf("%d\n",a[t]);
	
	t=upper_bound(a,a+n,x,greater<int>())-a;//从头开始二分查找,返回找到的第一个小于要找数据的地址,如果没有找到,返回最后一个数据以后的一个地址(无意义) 
	if(t==n)t--;//如果未找到,t=n,向前推一位才有对应的数据 
	printf("%d\n",a[t]);
	
	return 0;
}

注意:这里面都是在调用函数时,加入了第三个参数greater<数据类型>()以后我们程序的排序或者查找都与原来相反所以 lower_bound和upper_bound都是在有序数组里面进行查找,返回地址,返回值是地址,还不能直接当作数据使用要与首地址相减才行,在一般情况下函数都会进行默认处理,如果想反着用,可以试一试加入这个

greater函数与less函数


三.库函数

简单了解一下

C语言库函数

tolower函数

四.容器

1.vector(不定长数组)
//vector的定义 
vector<数据类型> 名称;
//该容器包含在<vector>头文件里面

//vector的初始化 
vector<int> a(10);//初始化容器有十个元素 
vector<int> a(10,1);//初始化容器有十个元素全部为一 
//vector<int> b(10,1);
vector<int> a(b);//直接把容器b的元素全部赋值给容器a 
vector<int>a(b.begin(),b.begin+3);//把容器b内的前三个元素全部赋值给容器a 
//int b[5]={1,1,1,1,1};
vector<int> a(b,b+3);//把数组b的前三个元素赋值给容器a;


//vector的几种用法
#include<vector>
vector<int> a,b;
//b为容器,将b的0-2个元素赋值给容器a
a.assign(b.begin(),b.begin()+3);
//a含有4个值为2的元素
a.assign(4,2);
//第一个元素
a.front(); 
//第一个元素地址 
a.begin();
//最后一个元素
a.back(); 
//最后一个元素地址 
a.end();
//返回a的第i元素,当且仅当a存在
a[i];
//清空a中的元素
a.clear();
//判断a是否为空,空则返回true,非空则返回false
a.empty();
//删除a容器的最后一个元素
a.pop_back();
//删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束
a.erase(a.begin()+1,a.begin()+3);
//在a的最后一个容器后插入一个元素,其值为5
a.push_back(5);
//在a的第一个元素(从第0个算起)位置插入数值5,
a.insert(a.begin()+1,5);
//在a的第一个元素(从第0个算起)位置插入3个数,其值都为5
a.insert(a.begin()+1,3,5);
//b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6)
a.insert(a.begin()+1,b+3,b+6);
//返回a中元素的个数
a.size();
//返回a在内存中总共可以容纳的元素个数
a.capacity();
//将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10);
//将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.resize(10,2);
//将a的容量扩充至100,
a.reserve(100);
//b为容器,将a中的元素和b中的元素整体交换
a.swap(b);
//b为容器,容器的比较操作还有 != >= > <= <
a==b;
这里面说得比较杂乱,但是每一个都蛮重要的,特别是C语言数据溢出时就可以用 vector容器
容器数组:数组内的每一个元素都是一个容器
vector<int> a[maxn];
//第一维大小固定,不超过maxn,第二维是容器,大小不固定
vector<vector<int> > a;
//这个我不太能理解,找了一篇文章,可以参考一下
//注意一点,把> >与>>分清楚,中间一般空一格,否则可能编译错误
vector<vector<int> >用法

2.set(集合)
//set集合的定义
set<数据类型> 名称;
//该容器包含在<set>头文件里面

set<int> a; 

//插入数据
int temp;
s.insert(temp);
//指定删除数据temp
s.erase(temp);
//清空
s.clear(); 
//判断是否为空
s.empty();
//查找元素k,返回的是元素k的地址 
s.find(k);
//元素个数
s.size(); 
//二分查找k
s.lower_bound(k);//返回大于或等于k的第一个元素地址 
s.upper_bound(k);//返回大于k的第一个元素地址
set集合有两个特别之处
自动去重
自动排序(默认从小到大)(我还不知道怎么改他的排序emmm)
这两个功能非常友好,后面做其他题目可能会经常用到
示例

List查询指定元素的总数 java list查找某一个元素_c语言

这里面有一个类似于C语言里面指针的东西,叫做迭代器,iterator,实际上就是容器的指针,我后面会再写一篇文章解释迭代器

 迭代器

看完我写的文章还可以去看看其他博主的,我写的比较简略

set集合的运用


3.map(映射)

map也叫做关联容器,它最大的好处就是可以把两个任何数据类型的数据关联在在一起,使用在查找时非常方便

//map的定义 map<键(key)的类型,值(value)的类型> 容器名称; //该容器包含在<map>头文件里面 map<string,int> m; //map的赋值 m["aaa"]=100;//直接赋值,这个我们可以了解到 容器名称[键(key)]表示的时值(value) m.insert(pair<string,int>("aaa",100)); m.insetr(map<string,int>::value_type("aaa",100)); string s;int t;//间接赋值 m.insert(pair<string,int>(s,t)); m.insetr(map<string,int>::value_type(s,t)); //清空 m.clear(); //判空 m.empty() ; //删除某一组数据 m.erase(键(key));//直接删除,有返回值 map<string,int>::iterator it;//用迭代器删除 it=m.find(键(key)); m.erase(it); m.erase(m.begin(),m.end());//成片删除 //大小 m.size();

map容器其实有点类似于结构体,把多个不同数据的数据进行捆绑

示例

List查询指定元素的总数 java list查找某一个元素_蓝桥杯_02


 以上只是map的一些用法,有的我写的比较简单,有一些细节还要注意,还有其他的用法,可以再看看这篇文章

map容器


4.stack(栈)
这是一个标准的先入后出的容器,不需要太理解,可以把他看作一口井,先进去的被压在最底下,所以必须先把压在上面的拿出来才能移动下面的
//栈的定义
stack<数据类型> 容器名称;
//容器在<stack>头文件里面 

stack<int> s; 
//入栈,依次往后放入元素 
s.push(数据);
//出栈,直接删除栈顶元素 
s.pop(); 
//栈顶元素
s.top();
//判断空栈
s.empty();
//栈内元素的个

数 s.szie();

示例

List查询指定元素的总数 java list查找某一个元素_蓝桥杯_03

 stack比较复杂,我也不太能理解,还有堆,优先队列,都不太好理解

感觉这些容器大部分功能都差不多了,都是进行模仿,第一个vector讲得最详细,其他容器也可以类似的进行模仿,下面有一篇文章介绍stack,感觉蛮好的,但是看不太懂

stack详解


刚刚在写代码看见了那个判断容器是否为空,这里需要说一下一个东西,就是bool类型

布尔类型

在判断empty 时如果是空的就返回true,如果不是空的返回false

这个判空函数一定要看一下


5.queue(队列)

这是一个标准的先入先出的容器,不需要太理解,可以把他看作一个队伍,先排队的肯定先出来
//队列(queue)的定义
queue<数据类型> 容器名称;
//容器包含在<queue>头文件里面

queue<int> q;
//读入数据
int t;
q.push(t);
//弹出数据,删除队首元素
q.pop();
//队首元素
q.front();
//队末元素
q.back();
//判空
q.empty();
//队内元素个数
q.size();


示例

List查询指定元素的总数 java list查找某一个元素_蓝桥杯_04

 我刚刚尝试了一下用迭代器去遍历这整个容器,但是发现无法遍历,然后查到的信息表示队列似乎只能访问队首和对末的数据


对比

栈和队列

List查询指定元素的总数 java list查找某一个元素_数据_05

简单看一下吧 


6.list(链表)

链表相较于前两种,更加灵活,实用性很强,在后面的编程中会经常用到链表
//链表的定义
list<数据类型> 容器名称;
//容器list包含在<list>头文件里面

list<int> l;

//尾部插入元素
int t;
l.push_back(t);
//头部插入元素
int t;
l.push_front(t);
//固定位置插入元素
l.insert(l.begin,t);//把元素t放入链表开头位置 
//弹出尾部元素
l.pop_back();
//弹出头部元素
l.pop_front();
//固定位置删除元素
l.erase(l.end);//删除链表尾部元素 
//清空
l.clear();
//判空
l.empty(); 
//尾部元素
l.back(); 
//头部元素 
l.front();
//链表内部反转
l.reverse();
//链表内部排序
l.sort();

示例1

List查询指定元素的总数 java list查找某一个元素_蓝桥杯_06

其实在看见前面的一些输入方法以后,链表最独特的应该是固定位置插入元素,但是可能不少人无法理解如何实现,因为迭代器必须从前向后或者从后向前连续遍历,无法直接找到之间某个位置的迭代器(地址),所以下面我会给出一个示例,我个人觉得有点无语,找迭代器(地址)真的是一个个遍历
示例2

List查询指定元素的总数 java list查找某一个元素_c语言_07

 这个示例我要放入代码解释,我被这个坑了快一个小时了

#include<iostream>
#include<list> 
using namespace std;
int main()
{
	list<int> l;
	int t,n,i,j;
	cin >> n;
	for(i=0;i<n;i++)
	{
		cin >> t;
		l.push_back(t);//尾插 
	}
	list<int>::iterator it;
	j=0;
	for(it=l.begin();it!=l.end();it++,j++)
	if(j==2)
	{
		cin >> t;
		l.insert(it,t);
	}
	for(it=l.begin();it!=l.end();it++)
	cout << *it << " ";
	cout << "\n";
	j=0;
	for(it=l.begin();it!=l.end();it++,j++) 
	if(j==3)	l.erase(it--);//这里比较重要,我调试了好久才编译成功
    //这里为什么要向前推一个位置,因为在每一次循环以后都会往后推一个位置,删除了一个元素以后,当前位置被被后面那个元素替代,所以如果要想遍历整个列表,就必须继续从这个位置往后推移,所以就得减一个与后面循环的增加抵消
	for(it=l.begin();it!=l.end();it++)
	cout << *it << " ";
	cout << "\n";
	return 0;
}

上面那个是我的拙见,希望各位大佬可以给出正确的解释方法


这篇文章已经前后拖延了一个月了,我一直没有时间补全,这学期课程太多了,所以更新的比较慢,但是还是会坚持的,C++代码真的是一个字,练,最近主课太多了,所以一直没写代码,最近开始做实验才发现前面学的C都忘了不少,先发一些这个STL初步吧,后面还会补全的