目录
数据结构与标准模板库
一、栈(后进先出)
void pop() 删除栈顶元素,出栈
void push(const TYPE &val)新元素val入栈,成为栈顶的第一个元素
stack<TYPE>StackName 变量定义
代码示例:
1.栈的简单操作
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack <int> s;//栈初始化
//struct node a;
//node a;
cout<<"Top: "<<s.top()<<endl;//查看栈顶元素
//printf("%d ",s.top());
cout<<"Size: "<<s.size()<<endl;//返回栈中的元素个数
s.pop();//删除栈顶元素
cout<<"Size: "<<s.size()<<endl;
if(s.empty())
{
cout<<"Is empty"<<endl;
}
else cout<<"Is not empty"<<endl;
for(int i=1;i<=5;i++)
{
scanf("%d ",&i);
s.push(i);//入栈
}
for(int i=1;i<=5;i++)s.pop(i);
return 0;
}
2.栈逆序输出
由于栈后进先出的特性,将一组数据全部入栈后依次出栈则可以实现逆序操作
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack <int> s;
int n,data;
scanf("%d ",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&data);
s.push(data);//入栈
}
while(!s.empty())
{
cout<<"Top: "<<s.top()<<endl;//取栈顶
s.pop();//出栈
}
return 0;
}
输入:
3
1 2 3
输出:
Top: 3
Top: 2
Top: 1
3.栈逆序输出任意长度的数
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack <int> s;
int data;
while(~scanf("%d",&data))//结束标志 回车+CTRL Z+回车
s.push(data);
while(!s.empty())
{
printf("%d ",s.top());
s.pop();
}
return 0;
}
输入:
1 4 5
^Z
输出:
5 4 1
---------
^Z为输入的结束标志
4.栈逆序输出字符型(一串英文)
这段代码与之前代码的区别就是应用了结构体数组来输入栈中实现逆序操作。
#include <bits/stdc++.h>
#define MAXSIZE 20
using namespace std;
struct node//结构体数组
{
char m[MAXSIZE];
};
int main()
{
struct node b;
stack <struct node> s;
while(~scanf("%s",b.m))//结束标志 回车+CTRL Z+回车
s.push(b);
while(!s.empty())
{
printf("%s ",s.top().m);//取栈顶
s.pop();
}
return 0;
}
输入:
hello world !
^Z
输出:
! world hello
二、向量
stl容器向量(vector)是一个动态数组,随机存取任何元素都能在常数时间完成。
vector<TYPE>c 产生一个空Vector
c.size() 返回容器实际数据的个数
c.clear() 移除容器中的所有数据
c.empty() 判断容器是否为空
c.pop_back() 删除最后一个数据
c.push_back(elem) 在尾部加入一个数据elem
代码示例:
1.vector 动态数组
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
int i;
scanf("%d",&n);
vector <int> a(n);//大小为n,int类型的向量
//初始化向量
for(i=0;i<=n-1;i++)
{
scanf("%d",&a[i]);
}
a.push_back(10);//在尾部插入10
//打印向量
for(i=0;i<=n;i++)
printf("%d ",a[i]);
//输出向量实际数据的大小
printf("\n%d",a.size());
return 0;
}
/*
输入:
3
1 2 3
输出:
1 2 3 10
4
*/
2.vector double 逆序输出
带两个常量参数的构造函数,产生初始值为一个区间的向量。区间由一个半开区间[first,last)来指定。
如:
vector<int> v(first,last)
#include <bits/stdc++.h>
using namespace std;
double ar[10]={10.2,1.2,2.2,3.3,4.4,5.5,6.6,7.2,8.2,9.2};
int main()
{
vector <double> vec1(ar,ar+10);//半闭半开,不包括ar+10
printf("vec1:\n");
vector<double>::iterator p;//迭代器
for(p=vec1.end()-1;p>=vec1.begin();p--)//由后往前遍历
{
printf("%lf ",*p);
if(p==vec1.begin())
break;
}
printf("\n");
return 0;
}
输出:
vec1:
9.200000 8.200000 7.200000 6.600000 5.500000 4.400000 3.300000 2.200000 1.200000 10.200000
3.vector double 逆序输出2
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
double x;
int i;
vector<double>a;
scanf("%d",&n);
for(i=0;i<=n-1;i++)
{
scanf("%lf",&x);
a.push_back(x);
}
for(i=n-1;i>=0;i--)
{
printf("%.2lf ",a[i]);
}
return 0;
}
输入:
3
1.1 2.2 3.3
输出:
3.30 2.20 1.10
4.vector 输出整型和字符型
#include <bits/stdc++.h>
using namespace std;
int ar[10]={0,1,2,3,4,5,6,7,8,9};
char str[30]="Hello World";
int main()
{
//创建一个向量,起始位置为ar,终止位置ar+10,不包括ar+10
vector <int> vec1(ar,ar+10);
//str 和str+strlen(str) 标识起始和结束地址
vector <char> vec2(str,str+strlen(str));
//vector<int> vec3(vec1);
printf("vec1:\n");
vector<int>::iterator p;
for(p=vec1.begin();p!=vec1.end();++p)
printf("%d ",*p);
printf("\n");
printf("vec2:\n");
vector<char>:: iterator pa;
for(pa=vec2.begin();pa!=vec2.end();++pa)
printf("%c ",*pa);
printf("\n");
return 0;
}
vec1:
0 1 2 3 4 5 6 7 8 9
vec2:
H e l l o W o r l d
5.vector 动态数组野指针问题
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,x;
int i;
scanf("%d",&n);
vector <int> a;
for(i=0;i<=n-1;i++)
{
scanf("%d",&x);
a.push_back(x);
}
a.push_back(10);
for(i=0;i<=n;i++)
printf("%d ",a[i]);
printf("\n%d",a.size());
return 0;
}
输入:
3
1 2 3
输出:
1 2 3 10
4
三、映射
map c(beg,end,op) 以op为排序准则,利用【beg;end】中的元素生成一个map
map <Keytype,elem,op> 键类型,元素类型,排序准则
map<string,float>::iterator pos 声明迭代器
pos->first 获取该元素的key
pos->second 获取该元素的value
代码示例:
1.map 容器的使用
#include <bits/stdc++.h>
using namespace std;
int main()
{
map <string,float,less<string> > c;// 按key的值排序 less 升序
//map <string,float,greater<string> > c;
// 按key的值 greater 降序
c.insert(make_pair("banana",1.72));
c.insert(make_pair("cat",30.69));
c["dog"]=15.66;
c["apple"]=7.75;
map<string,float>::iterator pos;
for(pos=c.begin();pos!=c.end();pos++)
{
printf("%s %f\n",pos->first.c_str(),pos->second);
}
c.clear();
return 0;
}
apple 7.750000
banana 1.720000
cat 30.690001
dog 15.660000
2.map 容器的使用2
#include <bits/stdc++.h>
using namespace std;
int main()
{
map <int,float,greater<int> > c;
// key value greater 降序
c[3]=7.75;
c.insert(make_pair(7,1.72));
c.insert(make_pair(5,30.69));
c[9]=15.66;
map<int,float>::iterator pos;
for(pos=c.begin();pos!=c.end();pos++)
{
printf("%d %f\n",pos->first,pos->second);
}
c.clear();
return 0;
}
9 15.660000
7 1.720000
5 30.690001
3 7.750000
3.map 容器的使用double
#include <bits/stdc++.h>
using namespace std;
int main()
{
map <double,float,greater<double> > c;
// key value greater 降序
c[3.44]=7.75;
c.insert(make_pair(7.77,1.72));
c.insert(make_pair(5.88,30.69));
c[9.44]=15.66;
map<double,float>::iterator pos;
for(pos=c.begin();pos!=c.end();pos++)
{
printf("%lf %f\n",pos->first,pos->second);
}
c.clear();
return 0;
}
9.440000 15.660000
7.770000 1.720000
5.880000 30.690001
3.440000 7.750000
四、列表(List)
线性链表结构,双链表,每个节点都包括一个信息块Info(即实际存储的数据)、一个前驱指针Pre、一个后驱指针Post。
list<TYPE> c(n,type) 产生拥有n个元素的list,每个元素都是type
void pop_back() 删除列表的最后一个元素
void pop_front() 删除列表的第一个元素
void push_back(const TYPE &val) 在尾部插入val
void push_front(const TYPE &val) 在头部插入val
void sort() 排序,默认升序
void reverse() 翻转所有元素
代码示例:
1.list 的使用
#include <bits/stdc++.h>
using namespace std;
int main()
{
list<int> mylist(5,100);
mylist.push_front(-13);//在列表头部插入-13
mylist.push_back(300);//在列表尾部插入300
list<int>::iterator it= mylist.begin();
//mylist.erase(it);
for(it=mylist.begin();it!=mylist.end();++it)
{
printf("%d ",*it);
}
printf("\n");
mylist.clear();
return 0;
}
-13 100 100 100 100 100 300
2.list的使用(逆置)
#include <bits/stdc++.h>
using namespace std;
int main()
{
list<int> mylist(5,100);
mylist.push_front(-13);
mylist.push_back(300);
list<int>::iterator it;
list<int>::iterator itw= mylist.end();
list<int>::iterator itt= mylist.begin();
--itw;
--itt;
//mylist.erase(it);
for(it=itw;it!=itt;--it)
{
printf("%d ",*it);
}
printf("\n");
mylist.clear();
return 0;
}
300 100 100 100 100 100 -13
3.list的使用(逆置)2
#include <bits/stdc++.h>
using namespace std;
int main()
{
list<int> mylist(5,100);
mylist.push_front(-13);
mylist.push_back(300);
list<int>::iterator it=mylist.end();
//mylist.erase(it);
--it;
for(;it!=mylist.begin();--it)
printf("%d ",*it);//1-n+1 n-2 n+1-2
printf("%d ",*it);//1
printf("\n");
mylist.clear();
return 0;
}
4.list的使用(逆置)3
#include <bits/stdc++.h>
using namespace std;
int main()
{
list<int> mylist(5,100);
mylist.push_front(-13);
mylist.push_back(300);
list<int>::iterator it;
list<int>::iterator itw= mylist.end();
--itw;
//mylist.erase(it);
for(it=itw;it!=mylist.begin();--it)
printf("%d ",*it);//1-n+1 n-2
printf("%d ",*it);//1
printf("\n");
mylist.clear();
return 0;
}
五、集合(Set)
集合Set是一个容器,它其中所包含的元素是唯一的。set容器默认排序规则为从小到大。
代码示例:
1.set元素的插入和输出
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <string> str;
set <string>::iterator pos;
str.insert("apple");
str.insert("orange");
str.insert("banana");
str.insert("grapes");
for(pos=str.begin();pos!=str.end();pos++)
{
//printf("%s\n",pos->c_str());//c_str()返回一个指向字符数组的指针
printf("%s\n",(*pos).c_str());
printf("\n");
}
str.clear();
return 0;
}
apple
banana
grapes
orange
2.set元素的插入和输出(int)
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <int> shu;
set <int>::iterator pos;
shu.insert(4);
shu.insert(2);
shu.insert(1);
shu.insert(3);
for(pos=shu.begin();pos!=shu.end();pos++)
{
//printf("%s\n",pos->c_str());
printf("%d\n",*pos);
printf("\n");
}
shu.clear();
return 0;
}
1
2
3
4
3.set元素的插入和输出(double)
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <double> shu;
set <double>::iterator pos;
shu.insert(4.22);
shu.insert(2.11);
shu.insert(1.23);
shu.insert(3.16);
for(pos=shu.begin();pos!=shu.end();pos++)
{
printf("%lf\n",*pos);
printf("\n");
}
shu.clear();
return 0;
}
1.230000
2.110000
3.160000
4.220000
六、队列(先进先出)
只允许在表头(队头)Front删除,表尾(队尾)Rear插入。
void pop() 删除队列的第一个元素
void push(const TYPE &val) 将val加入队列
代码示例:
1.容器Queue的使用
#include <bits/stdc++.h>
using namespace std;
int main()
{
queue <int> q;
q.push(1);q.push(2);q.push(3);q.push(9);
printf("%d\n",q.size());
printf("%d\n",q.empty());//true 1 false 0
printf("%d\n",q.front());
printf("%d\n",q.back());
while(!q.empty())
{
printf(" %d ",q.front());
q.pop();
}
return 0;
}
4
0
1
9
1 2 3 9
七、优先队列Priority Queue
队列中最大的元素总是位于队首,出队时将队列中最大元素出队。
示例代码:
1.优先队列的使用
#include <bits/stdc++.h>
using namespace std;
int main()
{
//priority_queue <int>que;//从大到小
priority_queue < int,vector<int>,less<int> >que;
//从大到小 大顶堆
que.push(12);
que.push(36);
que.push(48);
while(!que.empty())
{
printf("%d \n",que.top());
que.pop();
}
return 0;
}
48
36
12
2.优先队列的使用(小顶堆)
#include <bits/stdc++.h>
using namespace std;
int main()
{
//priority_queue <int>que;//从大到小
priority_queue < int,vector<int>,greater<int> >que;
//从小到大 小顶堆
que.push(12);
que.push(5);
que.push(48);
while(!que.empty())
{
printf("%d \n",que.top());
que.pop();
}
return 0;
}
5
12
48
3.优先队列的使用(double小顶堆)
#include <bits/stdc++.h>
using namespace std;
int main()
{
//priority_queue <int>que;//从大到小
priority_queue < double,vector<double>,greater<double> >que;
//从小到大 小顶堆
que.push(12.1);
que.push(36.2);
que.push(48.3);
while(!que.empty())
{
printf("%.2lf \n",que.top());
que.pop();
}
return 0;
}
12.10
36.20
48.30
4.优先队列的使用(double大顶堆)
#include <bits/stdc++.h>
using namespace std;
int main()
{
//priority_queue <int>que;//从大到小
priority_queue < double,vector<double>,less<double> >que;
//从大到小 大顶堆
que.push(12.1);
que.push(36.2);
que.push(48.3);
while(!que.empty())
{
printf("%.2lf \n",que.top());
que.pop();
}
return 0;
}
48.30
36.20
12.10
5.学生成绩降序(<<)输出(自定义类型)
#include <bits/stdc++.h>
using namespace std;
struct info
{
char name[20];
float score;
//友元
friend bool operator < (const info &a,const info &b)
{
return a.score<b.score;//降序
//return a.score>b.score;//(<>)升序
}
};
int main()
{
priority_queue <info> pq;
info in;
strcpy(in.name,"Jack");
in.score=68.5;
pq.push(in);
strcpy(in.name,"Bomi");
in.score=18.5;
pq.push(in);
strcpy(in.name,"Peti");
in.score=90;
pq.push(in);
while(!pq.empty())
{
printf("%s:%.2lf\n",pq.top().name,pq.top().score);
pq.pop();
}
return 0;
}
Peti:90.00
Jack:68.50
Bomi:18.50
7.学生成绩降序(<<)输出2(自定义类型)
#include <bits/stdc++.h>
using namespace std;
struct info
{
char name[20];
float score;
//友元
friend bool operator < (const info &a,const info &b)
{
return a.score<b.score;//降序
//return a.score>b.score;//(<>)升序
}
};
int main()
{
priority_queue <info> pq;
info in;
for(int i=0;i<=2;i++)
{
scanf("%s%f",&(in.name),&(in.score));
pq.push(in);
}
while(!pq.empty())
{
printf("%s:%lf\n",pq.top().name,pq.top().score);
pq.pop();
}
return 0;
}
jack 45
bom 12
we 34
jack:45.000000
we:34.000000
bom:12.000000
8.学生数学语文成绩降序(<<)输出
#include <bits/stdc++.h>
using namespace std;
struct student{
int Chinese;
int math;
int total;
}a[6];
bool compare(const student &x,const student &y)
{
return x.total<y.total;//升序
}
int main()
{
int i;
for(i=0;i<=4;i++)
{
scanf("%d %d",&(a[i].Chinese),&(a[i].math));//语文、数学成绩
a[i].total=a[i].Chinese+a[i].math;//总成绩
}
sort(a,a+5,compare);//排序
printf("\n");
for(i=0;i<=4;i++)
{
printf("%d %d %d\n",a[i].Chinese,a[i].math,a[i].total);
}
return 0;
}
输入:
21 33
22 44
55 66
33 55
19 70
输出:
21 33 54
22 44 66
33 55 88
19 70 89
55 66 121
本博客资料、代码来源于清华大学出版社算法设计与分析,本博客仅用于个人学习,可能存在纰漏,敬请批评指正。