十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
写在前面
创新互联是专业的通化网站建设公司,通化接单;提供成都网站建设、网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行通化网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!【算法设计与分析】这一系列是作者在本学期学习算法的时候做的笔记,由于本人水平有限,对很多概念的理解比较浅显😭,欢迎各位大佬多多评价,多多批评指正,希望与大家互相交流学习👻。
参考资料
[1] Mark Allen Weiss 《数据结构与算法分析C语言描述》
[2] Stephen Prata《C Primer Plus》
[3] 余文溪 黄襄念《C++ STL——数据结构与算法实现》
[4] HUST算法设计与分析组 PPT
[5]高畅 《LeetCode 101:和你一起轻松刷题》
最后更新时间
2022-11-25 22:40
定义
#includevectorname;
上面这个定义其实就是相当于定义了一个一维数组name[SIZE]
,只不过其长度可以根据需要进行变化。
如果typename也是一个STL容器,定义的时候需要在>>符号之间加上一个空格,防止编译器误以为是移位符。
vector>name;
定义二维数组有以下两种方式:
vectorname[SIZE];
vector>name;
动态开辟二维vector:
int m = 3;//行数
int n = 4;//列数
vector>Name(m, vector(n));//默认初始化为0
for (int i = 0; i< m; i++)
{for (int j = 0; j< n; j++)
{cout<< Name[i][j];
}
cout<< endl;
}
内部元素的访问
name[index]
即可。vector::iterator it;
然后就可以用这个迭代器来访问容器内的元素:
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 5; i++)
{vi.push_back(i);
}
vector::iterator it = vi.begin();
for (int i = 0; i< 5; i++)
{cout<< *(it + i);
}
return 0;
}
其中,vi.begin()
为取vi的首元素地址,it指向这个地址。再引入vi.end()
,它是去取尾元素地址的下一个地址,不是尾元素地址。
还有另一种使用迭代器遍历的方法:
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 5; i++)
{vi.push_back(i);
}
for (vector::iterator it = vi.begin(); it != vi.end(); it++)
{cout<< *it;
}
return 0;
}
注意vector迭代器并不支持it
it!=vi.end()
。
push_back()
push_back(x)
就是在vector最后添加一个元素x,时间复杂度为
O
(
1
)
O(1)
O(1)。
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 3; i++)//将1、2、3依次插入vi末尾
{vi.push_back(i);
}
for (int i = 0; i< vi.size(); i++)
{cout<< vi[i];
}
return 0;
}
pop_back()
pop_back
用以删除vector的尾元素,时间复杂度
O
(
1
)
O(1)
O(1)。
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 3; i++)//将1、2、3依次插入vi末尾
{vi.push_back(i);
}
vi.pop_back();
for (int i = 0; i< vi.size(); i++)
{cout<< vi[i];//输出1 2
}
return 0;
}
size()
size()
用来获得vector中元素的个数,返回unsigned类型,时间复杂度为
O
(
1
)
O(1)
O(1)。
clear()
clear()
直接清空vector中所有的元素,时间复杂度为
O
(
N
)
O(N)
O(N),N为元素的个数。
insert()
insert(it,x)
用来向vector的迭代器it处插入一个元素x,时间复杂度为
O
(
N
)
O(N)
O(N)。
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 5; i++)
{vi.push_back(i);//1 2 3 4 5
}
vi.insert(vi.begin() + 2, -1);
for (int i = 0; i< vi.size(); i++)
{cout<< vi[i];//1 2 -1 3 4 5
}
return 0;
}
erase()
1. 删除单个元素erase(it)
。
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 5; i++)
{vi.push_back(i);//1 2 3 4 5
}
vi.erase(vi.begin() + 3);
for (int i = 0; i< vi.size(); i++)
{cout<< vi[i];//1 2 3 5
}
return 0;
}
2.删除一个区间内的所有元素earse(first,last)
,区间左闭右开。
#include#includeusing namespace std;
int main()
{vectorvi;
for (int i = 1; i<= 5; i++)
{vi.push_back(i);//1 2 3 4 5
}
vi.erase(vi.begin() + 1, vi.begin() + 3);
for (int i = 0; i< vi.size(); i++)
{cout<< vi[i];//1 4 5
}
return 0;
}
主要用途
定义
setname;
set翻译为集合,是一个内部自动有序且不含重复元素的容器。
元素访问
注意,由于除了vector和string之外的STL容器都不支持*(it+i)
的访问方式,所以只能按以下方式枚举:
#include#includeusing namespace std;
int main()
{setst;
st.insert(3);
st.insert(5);
st.insert(2);
st.insert(3);
for (set::iterator it = st.begin(); it != st.end(); it++)
{cout<< *it<< endl; //2 3 5
}
return 0;
}
可以发现,set内的元素自动递增排序,且自动去除了重复的元素。
insert()
insert(x)
可以将x插入到set容器中,并且自动排序和去重,时间复杂度为
O
(
log
N
)
O(\log N)
O(logN),N为元素个数。
find()
find(value)
返回set中对应值为value的迭代器,时间复杂度为
O
(
log
N
)
O(\log N)
O(logN)。若不存在,则返回st.end()
#include#includeusing namespace std;
int main()
{setst;
for (int i = 1; i<= 3; i++)
{st.insert(i);
}
set::iterator it = st.find(2);
cout<< *it<< endl;
it = st.find(4);
if (it == st.end())
{cout<< "Not found"<< endl;
}
return 0;
}
erase()
1.删除单个元素:st.erase(it)
,it为所需要删除元素的迭代器,可结合find()函数实现,时间复杂度
O
(
1
)
O(1)
O(1)。或者st.erase(value)
,value为所需要元素的值,时间复杂度
O
(
log
N
)
O(\log N)
O(logN)。
st.erase(st.find(100));
st.erase(100);
2.删除一个区间内的所有元素:st.erase(first,last)
,first为所需要删除区间的起始迭代器,last为所需要删除区间的末尾迭代器的下一个地址。
st.erase(st.find(100),st.end());//删除元素30到末尾之间的元素
size()
获取set内元素的个数,时间复杂度
O
(
1
)
O(1)
O(1)。
clear()
清空set中所有的元素,时间复杂度
O
(
N
)
O(N)
O(N)。
主要用途
定义
#include//注意string和string.h是不一样的头文件
string str;
string str="abcd";
元素访问
string str="abcd";
cout<
string::iterator it;
string str="abcd";
for(it=str.begin();it!=str.end();it++)
{cout<<*it;
}
operatpr+=
string的加法,可以将string直接拼接起来。
string str1="abc";
string str2="def";
string str3=str1+str2;//将str1和str2拼接,赋给str3
str1+=str2;//将str2直接拼接到str1上
compare operator
两个string类型可以直接使用==,!=,<,<=,>,>=比较大小,比较顺序是字典序。
#include#includeusing namespace std;
int main()
{string str1 = "aa";
string str2 = "aaa";
string str3 = "abc";
string str4 = "xyz";
if (str1< str2) cout<< "ok1"<< endl;//ok1
if (str1 != str3) cout<< "ok2"<< endl;//ok2
if (str4 >= str3) cout<< "ok3"<< endl;//ok3
return 0;
}
length()/size()
length()
返回字符串存放的字符数,时间复杂度为
O
(
1
)
O(1)
O(1),size()
与其用法基本相同。
insert()
insert(pos,string)
,在pos号位置插入字符串string,时间复杂度
O
(
N
)
O(N)
O(N)。string str="abcxyz",str2="opq";
str.insert(3,str2);
cout<
insert(it,it1,it2)
,it为原字符串欲插入的位置,it2和it3为待插字符串的首尾迭代器,用来表示串[it2,it3)将被插在it的位置上,时间复杂度
O
(
N
)
O(N)
O(N)。string str1="abcxyz",str2="opq";
str1.insert(str1.begin()+3,str2.begin(),str2.end());//abcopqxyz
erase()
erase(it)
,删除单个元素,it为元素的迭代器,时间复杂度
O
(
N
)
O(N)
O(N)。erase(first,last)
,删除区间内的元素,时间复杂度
O
(
N
)
O(N)
O(N)。erase(pos,length)
,pos为需要删除的起始位置,length为要删除的长度,时间复杂度
O
(
N
)
O(N)
O(N)。clear()
清空string中的所有元素,时间复杂度
O
(
1
)
O(1)
O(1)。
substr()
substr(pos,len)
返回从pos开始,长度为len的子串,时间复杂度为
O
(
l
e
n
)
O(len)
O(len)
string::npos
它是一个常数,值为-1,用作find函数失配时的返回值。
find()
str1.find(str2)
,当str2时str1的子串时,返回其在str中第一次出现的位置,否则返回string::npos。str1.find(str2,pos)
从str1的pos号开始匹配,返回值同上。时间复杂度
O
(
m
n
)
O(mn)
O(mn),m和n分别是str1和str2的长度。
replace()
str1.replace(pos,len,str2)
把str1从pos号位置开始,长度为len的子串替换为str2。str1.replace(it1,it2,str2)
把str1的迭代器[it1,it2)范围的子串替换为str2。
#include#includeusing namespace std;
int main()
{string str1 = "abcxyz";
string str2 = "opq";
str1.replace(3, 4, str2);
cout<< str1<< endl;//abcopq
str1.replace(str1.begin() + 1, str1.end(), str2);
cout<< str1<< endl;//aopq
}
2.4 mapmap翻译为映射,类似于hash表,能将某个类型的元素映射到另一个类型的元素。
定义
mapmp;
其中前一个为键(key),后一个为值(value)。map中的键是唯一的。如下面的代码:
mapmp;
mp['c']=20;
mp['c']=30;
最后c的映射应该为30,20被覆盖掉。
元素访问
1.通过下标访问。
2.通过迭代器访问。
因为map的每一对映射都有两个typename,所以map可以使用it->first
和it->second
来分别访问map中的key和value。
另外,map中的元素会以键的次序从小到大自动排序,其内部使用红黑树实现。
find()
find(key)
返回键为key的映射的迭代器,时间复杂度为
O
(
N
)
O(N)
O(N)。
#include#include
erase()/size()/clear()
与前面大致相同,不再介绍。
map的常见用途
queue翻译为队列,在STL中是一个先进先出的容器。
定义
queuename;
元素访问
由于queue本身是一种先进先出的限制性数据结构,因此只能通过front()
来访问队首元素,或back()
访问队尾元素。
#include#includeusing namespace std;
int main()
{queueq;
for (int i = 1; i<= 5; i++)
{q.push(i);//将i入队
}
cout<< q.front()<< endl;//1
cout<< q.back()<< endl;//5
return 0;
}
push()
push(x)
将x入队,时间复杂度
O
(
1
)
O(1)
O(1)。
pop()
pop()
将队首元素出列,时间复杂度
O
(
1
)
O(1)
O(1)。
front()/back()
分别获得队首元素和队尾元素,时间复杂度
O
(
1
)
O(1)
O(1)。
empty()
empty()
检测queue是否为空,返回true则为空,返回false则非空,时间复杂度
O
(
1
)
O(1)
O(1)。
size()
返回queue中元素的个数,时间复杂度
O
(
1
)
O(1)
O(1)。
queue常见用途
称为优先队列,其底层是用堆来实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
定义
priority_queuename;
元素访问
优先队列没有front()和back(),只能通过top()函数访问队首元素,也称堆顶元素。
#include#includeusing namespace std;
int main()
{priority_queueq;
q.push(3);
q.push(4);
q.push(1);
cout<< q.top()<< endl;//4
return 0;
}
push()/pop()/empty()/size()
与queue相同,不再介绍。
优先级的设置
priority_queueq;
priority_queue,less>;
priority_queue,greater>;
其中,第二个参数vector
是用来承载底层数据结构堆的容器,第三个参数则是对第一个参数的比较类,less
表示数字越大的优先级越大,greater
表示数字越小优先级越大。
struct fruit
{string name;
int price;
}
如果想要按照水果价格越高优先级越高排序,则需要重载运算符"<":
struct fruit
{string name;
int price;
friend bool operator< (fruit f1,fruit f2)
{return f1.price< f2.price;//价格高优先级高
}
}
注意,如果重载大于号会显示编译错误,因为从数学上来说只需重载小于号即可(aa,a==b等价于!(a同理,若想要以价格低的水果为优先级高的次序输出,只需要把return中的小于号改为大于号即可。
struct fruit
{string name;
int price;
friend bool operator< (fruit f1,fruit f2)
{return f1.price >f2.price;//价格低优先级高
}
}
另外,还可以将函数写在结构体外,即:
struct cmp
{bool operator () (fruit f1,fruit f2)
{return f1.price< f2.price;
{}
在这种情况下,需要使用第一种方法定义优先队列:
priority_queue,cmp>p;
常见用途
priority_queue可以解决一些贪心问题,也可以对迪杰斯特拉算法进行优化。
stack翻译为栈,在STL种是一个后进后出的容器。
定义
stackname;
元素访问
由于stack是一个后进后出的数据结构,所以只能通过top()来访问栈顶的元素。
push()/top()/pop()/empty()/size()
与前面大致相同,不再介绍。
常见用途
stack常用来模拟实现一些递归,防止程序对栈内存的限制而导致程序运行出错。
pair将两个元素绑在一起作为一个合成元素。
定义
#includepairname;
元素访问
pair中只有两个元素,分别是first和second,只需按照正常结构体的方式去访问即可。
比较操作数
两个pair类型数据可以直接使用“==”,“<=”等比较大小,比较规则是现以first的大小作为标准,只有当first相等时才会去判别second的大小。
常见用途
用来代替二元结构体及其构造函数,节省编码时间。还可以作为map的键值对进行插入,如:
mapmp;
mp.insert(make_pair("heihei",5));
mp.insert(pair("haha",10));
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧