C++ 语言学习 day09 STL vector list map set queue


1.标准模板库
     定义:标注模板库 惠普实验室开发的一些列统称
     组成部分:
         容器:特殊的数据机构用来存放数据。
         迭代器:用来遍历,底层是一些列的指针组成。用来通过迭代器操作容器
         算法:多容器的算法操作,排序,查找等操作
         空间配置器:管理模块类
         配接器: 仿函数:  对象( 参数)
         组件的关系:各个部分组成的关系
容器:容器是用来存放数据的,和数据结构中的队列 双向链表栈!


2..vector--- 动态数组
      连点: 顺序存放 ,可以改变数组大小,数组在尾部添加和移除数据非常快,但是在中间或者头部添加删除数据就比较慢了。
      可以不指定大小,直接使用
     构造: 无参构造: vector<类型> 对象;
                有参构造:vector(size_t n,T x);  用n个x构建数组。
                                  vector<int> v(2,10);
                 拷贝构造 :vector(const T& X);
                                     vector<int> x(v);


     迭代器:iterator 是一种可以变量容器元素的数据类型(理解成内部类)。可以理解成容器和操作容器算法的中间。
      begin()   迭代器执行容器的首位置  
      end()       迭代器执行容器的尾位置下一个
     迭代器定义格式: vector<int>::iterator  it = arr.begin();



     成员函数:
     size()  ---  获取vector的元素个数
                      案例:vec.size() 一般用于for循环中
     clear(); 清空vector中的内容,size变成0,capacity不会变
     empty(); 判断vector是否为空,如果为空则结果为真
     insert(迭代器位置,值):在某一个位置插入值,底层会把所有位置后的数据往后移动,效率比较低下
     erase(): 删除vector的一个数据或者某一个范围的数据
               第一种:删除某一个数据   vector.erase(迭代器位置) 删除迭代器位置的元素
               第二种:删除某一个范围的数据  案例
     vector.erase(vc.begin(),vc.begin()+4),会删除第一个到第三个元素,第四个元素不会删除;
      push_back();在尾部添加一个元素,效率比较高。参数是需要添加的值
     pop_back(); 在尾部删除一个元素,没有返回值
     capacity():得到vector的容量,可以使用的总大小。


代码:程序作用   定义一个学生的结构体,有姓名年龄,学生id。(用vector存放数据)
    如果输入1则尾部添加一个学生,输入2则打印学生信息,输入3则随机位置插入学生信息,输入4则班级解散。

头文件

student.h

#ifndef STUDENT_H
#define STUDENT_H
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
using namespace std;
typedef struct student
{
    int id;
    string name;
}stu;
void caidan(vector<stu>&q);
void zuoyong1(vector<stu> &q,stu a);//尾部添加学生信息
void zuoyong2(vector<stu> &q);//打印学生信息
void zuoyong3(vector<stu> &q,stu a,int n);//随机位置插入学生信息
void zuoyong4(vector<stu> &q);//清空学生信息


#endif // STUDENT_H

student.cpp

#include "student.h"
void caidan(vector<stu> &q)
{
    int a;

    cout<<"请输入您的选择:";
    cin>>a;
    if(a==1)
    {
        stu b;
        cout<<"请输入学生的id:";
        cin>>b.id;
        cout<<"请输入学生的name : ";
        cin>>b.name;
        zuoyong1(q,b);
    }
    if(a==2)
    {
        zuoyong2(q);
    }
    if(a==3)
    {
        stu b;
        int n;
        cout<<"请输入学生的id:";
        cin>>b.id;
        cout<<"请输入学生的name : ";
        cin>>b.name;
        cout<<"请输入插入的数据: ";
        cin>>n;
        zuoyong3(q,b,n);
    }
    if(a==4)
    {
       zuoyong4(q);
    }


}
void zuoyong1(vector<stu> &q,stu a)//尾部添加学生信息
{
    q.insert(q.end(),a);//地址  ++ 数据
    getchar();
    caidan(q);
}
void zuoyong2(vector<stu> &q)//打印学生信息
{
    vector<stu>::iterator it =q.begin();
    for(it=q.begin();it!=q.end(); it++)//it++ 遍历下一个
    {
        cout<<"学生的id :  "<<it->id<<"   ";
        cout<<"学生的名字: "<<it->name<<endl;
    }
     getchar();
    caidan(q);
}
void zuoyong3(vector<stu> &q,stu a,int n)//随机位置插入学生信息
{
    q.insert(q.begin()+n,a);
     getchar();
    caidan(q);
}
void zuoyong4(vector<stu> &q)//清空学生信息
{
    q.clear();
     getchar();
    caidan(q);
}

main.cpp 

#include <iostream>
#include <vector>
#include<list>
#include<cstdlib>
#include"student.h"
#include"bank.h"
using namespace std;

void show(vector<int> &vec1)//打印动态数组的元素
{
    //begin() 是开始!
    //end() 是结束!
    vector<int>::iterator it =vec1.begin();
    for(it=vec1.begin();it!=vec1.end(); it++)//it++ 遍历下一个
    {
        cout<<*(it)<<"  ";
    }
    cout<<"元素的个数: "<<vec1.size()<<endl; //获得元素个数
}



int main(int argc, char *argv[])
{
    /*
    vector<int>vec1;//无参构造
    vector<int>vec2(5,10);//有参构造 ,4个 int 类型的数值  10存入动态数组
    vec1=vec2;//拷贝构造
    show(vec1);
    vec1.pop_back();//尾部删除
    show(vec1);


    vec1.clear();//清空动态数组 vector
    //判断动态数组 vector 是否为空
    if(vec1.empty())
    {
        cout<<"vector 是空的!"<<endl;
    }
    else
    {
        cout<<"vector 不是空的!"<<endl;
    }

    //插入数据
    vec1.insert(vec1.end(),110);//地址  ++ 数据 //这里插入的数据是哪里 就插入哪里,  begin()  -》下标为  0  的位置
    show(vec1);

    //在任意的位置删除元素
    vec1.erase(vec1.begin());//括号里面的数据是 迭代器的地址
    show(vec1);


    //vec2 插入数据
    vec2.insert(vec2.begin(),110);
    show(vec2);

    //删除固定范围的数据
    vec2.erase(vec2.begin(),vec2.begin()+1);//前面那个数据不会删除,1 2 3 4   的动态数组只会删除  1   第一个数据,  因为begin 是开始的 0  吧!
    show(vec2);

    //开始的时候申请的空间大小,是开始申请的2 倍,等空间不够的时候再次申请!!
    cout<<"容量空间大小: "<<vec2.capacity()<<endl;//容量空间
*/



    //建立动态数组
    vector<stu> q;
    //运用菜单
    caidan(q);


    return 0;
}


3.list(双向链表)
    头文件: #include<list>
    特点: list是双向链表,在任意位置添加和删除都方便,效率高,但查找不容易,不可以通过下标操作。
     构造:
        第一个:空的构造函数   list()
        第二个: 拷贝构造   list(const list& other)
        第三个:list(int n,T val); 包含n个val元素
        第四个:用某一个容器的某一部分进行构造
                     list(T first,T last)  包含[ first ,last)
      成员函数: 
         首元素: front()
         尾元素: back()
         判断空:empty()
         得大小: size()
         清空: clear()
         尾部添加:push_back()
         尾部删除: pop_back()
         头部添加: push_front()
         头部删除:pop_front()
         添加元素: insert()
         交换list: swap()
         链表排序: sort()
         链表反转:  reverse() 


代码:程序 功能: 测试list 的函数

main.c

#include <iostream>
#include <vector>
#include<list>
#include<cstdlib>
#include"student.h"
#include"bank.h"
using namespace std;


int main(int argc, char *argv[])
{
   

    list<int>mylist1;//无参构造
    list<int>mylist2(5,6);//有参构造 定义 5个 6
    list<int>mylist3(mylist2);//拷贝构造
    vector<int>vct(10,20);
    list<int>mylist4(vct.begin()+3,vct.end()-2);//拷贝了5个! 20
    cout<<mylist3.size()<<endl;//元素个数
    mylist3.pop_front();//头部删除
    mylist1.insert(mylist1.begin(),111);//任意位置添加元素
    mylist1.reverse();//list 反转
    mylist1.swap(mylist3);//list 的相互交换
    mylist1.sort();//排序函数 固定的升序
    //                第一个地址        第二个地址
    mylist1.erase(mylist1.begin(),mylist1.end());//list 的开始位置,到list 末尾的位置,全部删除




    return 0;
}


4.deque(双向队列)
     队列特点:先进先出
        deque是在vector和list的组合,可以在两端push和pop
        可以随机访问的,可以使用下标操作,等价vector中的at。
        
    常用函数
      deque.assign(begin(),end())     赋值 把[begin,end)的数据赋值给deque
      deque.assign(n,val) ; 把n个val赋值给deque
      deque.at(x), 得到下标是x的数据元素,如果越界会抛出异常out_of_rang
      deque.back() ; 得到最后一个元素
       deque.front(); 得到首元素
        deque.begin()  迭代器,指向首元素
        deque.end() ;迭代器中执行尾元素
      deque.clear()  清空队列
       deque.size()  得到队列的容器
       deque.push_back(val)   尾部添加
        deque.pop_back()   尾部删除
         deque.push_front()  头部添加
         deque.rbegin();  反向迭代器,指向最后一个,it++ 指向倒数第二个
      deque.resize()  重新指定长度, 返回实际长度大小


代码:

#include <iostream>
#include <deque>
using namespace std;

void show(deque<int> de)//打印队列数据
{
    deque<int>::const_reverse_iterator  it = de.rbegin();
    while (it != de.rend())
    {
        cout << *it << " ";
        it++;
    }
    cout << "\n-------------------"<<endl;
}

int main()
{
    deque<int>  de;//无参构造
    for (int i = 0;i < 5;i++)
        de.push_back(i);//尾部添加数据
    de.assign(5, 10);//把5 个 10 的值赋给 de

    show(de);
    de.pop_front();//头部删除
    show(de);
    cout << de.at(1) << endl;
   
    de.resize(100);
    show(de);
    de.clear();
    show(de);

    return 0;
}

5.set(集合)
     作用:叫做集合,容器中不允许有相同的数据,并且数据自动排序。  
              底层叫红黑树的平衡二叉树(红黑树) 也是一种容器

 

 


代码:

#include <iostream>
#include <set>
using namespace std;

void show(set<int> de)
{
    set<int>::iterator  it = de.begin();
    while (it != de.end())
    {
        cout << *it << " ";
        it++;
    }
    cout << "\n-------------------" << endl;
}
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,98,90 };
    //把数组中所有元素添加到 set中
    set<int> myset(arr,arr+sizeof(arr)/sizeof(arr[0]));
    myset.insert(911);
    set<int>::iterator  it = myset.begin();
    //c++的新语法
    for (auto& i : myset)
    {
        cout << i << endl;
    }
    show(myset);
    myset.erase(5);
    show(myset);
    try{
        set<int>::const_iterator cit = myset.find(9011);
    }
    catch (...)
    {
     //   cout << *cit << endl;
    }
   
    std::cout << "Hello World!\n";
}

6.   map(字典--地图)
    特点:字典--一个key值对应一个val,由两个部分组成。
             map则需要添加key也需要添加val所以要在map中放pair模板类
             map可以方便的查找,并且key是唯一的。
             底层是二叉树实现的。每次插入值的时候都需要重写构建一个树
    pair构造:
            无参构造:std::pair<key,val> x;
            有参构造:std::pair<key ,val> x(begin,end);
             拷贝构造:std::pair<key,val> x(const std::pair<key,val>& other);       



     map的构建:
          map<string,int> xxx;
     map成员函数
         添加数据:需要添加pair模板,    insert(pair<key,val>(1,2));
        begin():  迭代器第一元素
        end()  :迭代器最后一个元素
         at(int pos): 访问pos位置的元素
         rbegin() 反向迭代器
         erase(): 删除一个元素或者某个范围的元素,不可以使用反向迭代器
         size(): map的大小,实际存放数据元素
         find(key) 查找key对应的值,返回的是迭代器。
map中有两个成员变量,一个是first一个second ,迭代器中的first表示key,second表示val
         可以通过下标访问元素。也可以通过下标赋值,但下标是key。


代码:

#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<int, string> mymap;//建立一个  map  key 是  int  类型   val  是 string 类型
    mymap.insert(pair<int, string>(11, "ddanny1"));
    mymap.insert(pair<int, string>(2, "ddanny2"));
    mymap.insert(pair<int, string>(13, "ddanny3"));
    mymap.insert(pair<int, string>(1, "ddanny4"));
    mymap.insert(make_pair(6, "ddanny"));

    for (map<int, string>::iterator it = mymap.begin();
        it != mymap.end();it++)
    {
        cout << it->first<<": "<< it->second << endl;
    }
    //最大可以使用的map大小。
    cout << mymap.max_size() << endl;
    mymap[2] = "abc";
    //下标是key 所以13是key
    cout << mymap[13] << endl;
    cout << mymap.at(1) << endl;
    mymap[1] = mymap[2];
    cout << mymap[1] << endl;
    mymap.clear();//清除


}


   


7.queue 操作

queue 和 stack 有一些成员函数相似,但在一些情况下,工作方式有些不同:

  • front():返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
  • back():返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
  • push(const T& obj):在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。
  • push(T&& obj):以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。
  • pop():删除 queue 中的第一个元素。
  • size():返回 queue 中元素的个数。
  • empty():如果 queue 中没有元素的话,返回 true。
  • emplace():用传给 emplace() 的参数调用 T 的构造函数,在 queue 的尾部生成对象。
  • swap(queue<T> &other_q):将当前 queue 中的元素和参数 queue 中的元素交换。它们需要包含相同类型的元素。也可以调用全局函数模板 swap() 来完成同样的操作。

代码:

#include <cstdlib>
#include <iostream>
#include <queue>
  
using namespace std;
  
int main()
{
    int e,n,m;
    queue<int> q1;//创建队列
    for(int i=0;i<10;i++)
       q1.push(i); //入队
    if(!q1.empty())//判断是否为空
    cout<<"dui lie  bu kong\n";
    n=q1.size();//返回队列元素的数量
    cout<<n<<endl;
    m=q1.back();//返回队列最后的元素
    cout<<m<<endl;
    for(int j=0;j<n;j++)
    {
       e=q1.front();//返回队列开始的元素
       cout<<e<<" ";
       q1.pop();//出队
    }
    cout<<endl;
    if(q1.empty())
    cout<<"dui lie  bu kong\n";
    system("PAUSE");
    return 0;
}


8.stack

一:头文件

#include<stack>

二:定义stack

stack<int>  s;创建一个空的 stack 对象。

stack<int, list<int> >   s1;
stack<int, list<int> >   s2(s1);
利用 s1 ,创建一个以双向链表为底层容器的空堆栈对象 s2 。

 三:基本函数


empty() 堆栈为空则返回真

pop() 移除栈顶元素

push() 在栈顶增加元素

size() 返回栈中元素数目

top() 返回栈顶元素

swap()交换元素

四:用法示例

#include <iostream>
#include <stack>
#include <vector>
#include <string>
using namespace std;

int main() {
    int i = 0;
    stack<int> v;
    for (i=0;i<10;++i)
    {
        v.push(i);
        cout << v.top() << "已入栈"<<endl;

    }
    cout << "现在栈的容量" << v.size() << endl;
    for (i=0;i<10;++i)
    {
        cout << v.top() << "准备出栈" << endl;
        v.pop();
    }
    cout << "现在栈的容量" << v.size() << endl;
    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值