STL顺序容器的基本操作

容器主要分为:顺序容器和关联容器

顺序容器和关联容器,顺序容器主要有:vector、list、deque等。其中vector表示一段连续的内存地址,基于数组的实现,list表示非连续的内存,基于链表实现。deque双向队列与vector类似,但是对于首元素提供删除和插入的双向支持。关联容器主要有map和set。map是key-value形式的,set是单值。map和set只能存放唯一的key值,multimap和multiset可以存放多个相同的key值, 还有unorder_multimap等。

 

 

顺序容器

vector

 

/*
* 什么是vector, vector的特点
* vector类似一个动态数组,是一段地址连续的空间
* vector和array的区别:vector支持动态空间调整,随着元素的增加,大小会改变
*/

   // 初始化:

    vector<int> v;
    vector<int> v2(10);  // 可以容纳10个int
    vector<int> v3(10, 2); // 10个2
    vector<int> v4(v2);
    int arr[4] = {1,2,3,4};
    vector<int> v5(arr, arr+4);

    // 其他操作, 是vector容器自带的函数,不包含全局的算法(find查找,remove_if删除等)
    // 添加元素
     vec.push_back(3); // 在最后添加元素
     insert();  
     /*
        iterator insert( iterator loc, const TYPE &val );
        void insert( iterator loc, size_type num, const TYPE &val );
        void insert( iterator loc, input_iterator start, input_iterator end );
        insert() 函数有以下三种用法:

        在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器,
               在指定位置loc前插入num个值为val的元素
        在指定位置loc前插入区间[start, end)的所有元素 .

     */
     // 删:
    
     // erase
    iterator erase( iterator loc );
    iterator erase( iterator start, iterator end );
    //    erase函数要么删作指定位置loc的元素,要么删除区间[start, end)的所有元素.
    // 返回值是指向删除的最后一个元素的下一位置的迭代器.例如:

    vec.clear();        // 清空容器
    vec.pop_back();     // 移除尾部元素,无返回值


    //
    vec.back();         // 返回最有一个元素的引用
    vec.begin();              // 返回当前容器首元素的迭代器
    vec.end();            // 尾后迭代器
    vec.rbegin();         // rbegin函数返回指向当前vector末尾的逆迭代器
    vec.rend();         // rend()函数返回指向当前vector起始位置的逆迭代器. 类似与begin和end


    其他
    vec.empty();        // 判断是否为空
    vec.capacity();     // 返回当前vector在重新进行内存分配以前所能容纳的元素数量.
                        //    reserve()函数为当前vector预留至少共容纳size个元素的空间

                        //    void resize( size_type size, TYPE val );
    vec.resize();        // resize() 函数改变当前vector的大小为size,且对新创建的元素赋值val
    vec.size();          // 返回当前所容纳的元素个数
                        //    vec.swap(vec2)  // vec和vec2交换
    // 遍历:
    void print(vector<int>& vec)
    {
        for (int i = 0; i < vec.size(); i++)
            cout << vec[i] << " ";
        
        for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
        {
            cout << *it << " ";
        }
        for (auto item : vec)
        {
            cout << item << " ";
        }
        cout << endl;
    }
vector常用方法

 deque

支持随机访问和快速插入和删除

// 双向队列和向量很相似,但是它允许在容器头部快速插入和删除(就像在尾部一样)。
// 就是比vector多了两个方法:
push_front()
pop_back()
// 具体使用方法参考vector

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


void printDeq(deque<int> &d1)
{
    cout << "deque迭代器遍历:";
    for (deque<int>::iterator it = d1.begin(); it != d1.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl << endl;
}
void test41()
{
    deque<int> d1;
    d1.push_back(1);
    d1.push_back(3);
    d1.push_back(5);
    d1.push_front(-11);
    d1.push_front(-33);
    d1.push_front(-55);

    printDeq(d1);
    cout <<"头部元素:" << d1.front() << endl;
    cout <<"尾部元素:" << d1.back() <<endl;

    d1.pop_front(); // 弹出头部元素
    d1.pop_back();  // 弹出尾部元素

    cout << "弹出头部,和尾部之后: ";
    printDeq(d1);

    // 查找-33在数组下标的值
    deque<int>::iterator it = find(d1.begin(),d1.end(), -33);

    if (it != d1.end())
    {
                                // 计算下标
        cout <<"-33的数组下标是" << distance(d1.begin(), it) << endl;
    }
    else
    {
        cout <<"未找到"<<endl;
    }

}
int main40()
{
    test41();
    return 0;
}
deque例子

 

 

list

list,list是stl实现的双向链表,

与向量vector想比,它允许快速的插入和删除,但是随机访问却是比较慢

结构图:

 

 

优点:随意插入和删除,替换元素效率极高

缺点:查找慢(不能随机访问:就是只能从头开始遍历)

不建议想里面插入数据,效率太低 

/ 其他操作
// 初始化,创建
    list<int> lst1;          //创建空list
    list<int> lst2(3);       //创建含有三个元素的list
    list<int> lst3(3,2);     //创建含有三个元素为2的list
    list<int> lst4(lst2);    //使用lst2初始化lst4
    list<int> lst5(lst2.begin(),lst2.end());  //同lst4

    //
        lst1.assign(lst2.begin(),lst2.end());  //分配值,3个值为0的元素
        lst1.push_front(1);                    // 1加到list的首部
        lst1.push_back(10);                    //末尾添加值

         
        lst1.insert();                                                   //返回值是一个迭代器,指向被插入的元素。
        iterator insert( iterator pos, const TYPE &val );              // 插入元素val到位置pos
        void insert( iterator pos, size_type num, const TYPE &val ); // 插入num个元素val到pos之前
        void insert( iterator pos, input_iterator start, input_iterator end ); // 插入start到end之间的元素到pos的位置
    //
        lst1.pop_back();    // 删除链表的最后一个元素。
        lst1.pop_front();   // 删除连链表第一个元素 
        lst1.remove(1);     // 删除链表中所有的1  void
        lst1.remove_if( UnPred pr)// 以一元谓词pr为判断元素的依据,遍历整个链表。如果pr返回true则删除该元素。

        lst1.erase()
            iterator erase( iterator pos );
            iterator erase( iterator start, iterator end );
            erase()函数删除以pos指示位置的元素, 或者删除start和end之间的元素。 返回值是一个迭代器,指向最后一个被删除元素的下一个元素。
    
    lst1.clear()              // 清除所有元素
    //
        lst1.reverse();       // 将所有的list倒转
        lst1.swap(list2);     // 1和2交换
        lst1.unique();        // 删除重复的元素
            void unique();
            void unique( BinPred pr );
            unique()函数删除链表中所有重复的元素。如果指定pr,则使用pr来判定是否删除。

    //
        lst1.begin();         // 返回list的首元素的迭代器
        lst1.end();           // 返回list尾后迭代器
        lst1.front();         // 返回一个指向首元素的引用
        lst.back()              // 返回一个引用,指向list的最后一个元素。
        lst1.rbegin();        // 返回一个逆向迭代器,指向链表的末尾。 rend和begin和end用法类似

    // 其他
        lst1.empty();         // 判断是否为空 true为空
        lst1.max_size();      //max_size()函数返回链表能够储存的元素数目。
        lst1.merge()
            void merge( list &lst );
            void merge( list &lst, Comp compfunction );
            merge()函数把自己和lst链表连接在一起,产生一个整齐排列的组合链表。如果指定compfunction,则将指定函数作为比较的依据。

        lst1.resize(); 
            void resize( size_type num, TYPE val )// resize()函数把list的大小改变到num。被加入的多余的元素都被赋值为val
        lst1.size();         // 返回链表的元素数量
        lst1.sort();         // 排序
                void sort();
                void sort( Comp compfunction );
                sort()函数为链表排序,默认是升序。如果指定compfunction的话,就采用指定函数来判定两个元素的大小。

        // 遍历:

         // list不能随机访问 就是 it++正确,但是不能it+2

            it = l.begin();
            it++;
            it++;
            it++;  // 此时it指向第4个元素,元素为3
            l.insert(it, 100); // 在3前面插入100    
                
        for (auto it = lst1.begin(); it != lst1.end(); it++)
            cout << *it << " ";
        for (auto it : lst1)
            cout << it << " ";
        // 加上&可以修改值
        for (auto& it : lst1)
            cout << it << " ";
list常用操作

 

 

stack 

 


不允许遍历
C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。
    stack<int> s;
    s.push(1);  // 在栈顶添加元素
    s.push(2);
    s.top();  // 返回栈顶元素
    s.pop(); //删除栈顶元素
    s.empty(); // 判断栈空
    s.size();  // 判断栈中元素数量

 

//
// Created by lk on 18-6-3.
//
#include <iostream>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;

// 出栈
void printStack(stack<int> &sta)
{
    while(!sta.empty())
    {
        cout << sta.top() << " "; // 获取栈顶元素
        sta.pop();   // 出栈
    }
}
void test51()
{
    stack<int> s;
    // 入栈
    for(int i = 0; i != 10; i++)
    {
        s.push(i+1);
    }

    printStack(s);
}

// 栈模型
// 栈的算法 和数据类型的分离
// teacher节点
class Teacher
{
private:
    int   age;
    char  name[32];
public:
    Teacher()
    {
        age = 0;
        strcpy(name, "");
    }
    Teacher(char *name, int age)
    {
        this->age = age;
        strcpy(this->name, name);
    }
    void print()
    {
        cout << "name: " << name << "age: " << age << endl;
    }
    friend ostream& operator<<(ostream &out, Teacher &obj)
    {
        out << " name: " << obj.name << "  age: " << obj.age << endl;
        return out;
    }
};
// 存放类 类型
void test52()
{
    Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33);
    stack<Teacher> Stack_Tea;
    Stack_Tea.push(t1);
    Stack_Tea.push(t2);
    Stack_Tea.push(t3);

    while(!Stack_Tea.empty())
    {
        // Teacher重载了<<所以可以 cout<<
        cout <<Stack_Tea.top();
        Stack_Tea.pop();
    }
}
// 存放 类指针 类型
void test53()
{
    Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33);
    stack<Teacher*> Stack_Tea;
    Stack_Tea.push(&t1);
    Stack_Tea.push(&t2);
    Stack_Tea.push(&t3);

    // 出栈
    while(!Stack_Tea.empty())
    {
        cout << (* Stack_Tea.top()); // Stack_Tea.top() 就是&t1
        Stack_Tea.pop();
    }
}

int main()
{
    // test51();
     test52();
//    test53();
    return 0;
}
测试

queue

 


队列,栈都不能提前分配空间,需要进栈出栈, 不能遍历,
队和栈是两种封装好的数据结构
back()    返回最后一个元素
empty()    如果队列空则返回真
front()    返回第一个元素
pop()    删除第一个元素
push()    在末尾加入一个元素
size()    返回队列中元素的个数
//
// Created by lk on 18-6-3.
//
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

// 队列的基本类型
void test61()
{
    queue<int> q;  // 队列,栈都不能提前分配空间,需要进栈出栈
    // 入队
    q.push(1);
    q.push(3);
    q.push(5);

    cout << "队头元素:" << q.front() << endl; // 返回队头元素,不是删除,栈的是删除
    cout <<"队的大小:" << q.size() <<endl;
    cout << "队尾元素:" << q.back() << endl;
    // 出队
    cout <<"出队: ";
    while(!q.empty())
    {
        cout << q.front() << " ";
        q.pop();  // 删除队头元素
    }
}

// 队列的算法 和数据类型分离
// teacher 节点
class Teacher
{
private:
    int   age;
    char  name[32];
public:
    Teacher()
    {
        age = 0;
        strcpy(name, "");
    }
    Teacher(char *name, int age)
    {
        this->age = age;
        strcpy(this->name, name);
    }
    void print()
    {
        cout << "name: " << name << " age: " << age << endl;
    }
    friend ostream& operator<<(ostream &out, Teacher &obj)
    {
        out << "\tname: " << obj.name << " age: " << obj.age << endl;
        return out;
    }
};

// 存放类 类型
void test62()
{
    Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33);

    queue<Teacher> queue_Tea;  // 队列里面存放的是 Teacher的数据类型
    queue_Tea.push(t1);   // 入队
    queue_Tea.push(t2);
    queue_Tea.push(t3);

    cout << "老师节点的出队:\n";
    while(!queue_Tea.empty())
    {
        cout << queue_Tea.front() << "\n";
        queue_Tea.pop();  // 出队
    }
}
// 存放指针类型
// 类似栈 。。。
int main()
{
    // test61();
    test62();
    return 0;
}
测试

 

关联容器

https://www.cnblogs.com/xiaokang01/p/9130699.html 

posted @ 2018-06-03 22:03  Lucky&  阅读(1870)  评论(1编辑  收藏  举报
//返回顶部开始
//返回顶部结束