数据结构笔记(二)——线性表及STL容器

  1. 线性表的两种描述:数组/向量描述、链式描述,STL中的vector和list大致相当于这两种描述方法。
    ·数组/向量描述:所有元素依次存储在一片连续的存储空间中(静态存储)。
    ·链式描述:元素在内存中的存储位置是随机的(动态存储),每个元素都有一个明确的指针指向下一个元素的地址。

  2. STL vector的使用
    ·使用前应包含头文件和命名空间:

#include <vector>
using namespace std::vector

·创建和初始化:

vector<int> vec1;//默认构造函数,vec1为空
vector<int> vec2(size);//vec2初始化为size个元素,默认值是0
vector<int> vec3(size,value);//vec3初始化为size个值为value的向量
vector<int> vec4(vec3);//vec4是vec3的一个副本
vector<int> vec5(iter1,iter2);//用迭代器iter1和iter2之间的元素创建vec5
vector<int> vec6{1,2,3,4,5,6,7};//vec6用列表初始化

·容量和大小
在这里插入图片描述

auto length = vec.size();
vec.reserve(100);//容量增至100
auto cap = vec.capacity();
vec.empty();//若向量为空则返回true
vec.resize(n);//将长度改为n,超出的元素被删除
vec.resize(n,m);//长度改为n,超出的元素设为m

·元素的访问

vec[1] = 5;//使用索引访问
vec.at(1) = 5;//与[]用法相同,但可以检查越界
vec.front();//返回向量中第一个元素的引用
vec.back();//返回向量中最后一个元素的引用
vec.begin();//返回向量中第一个元素的迭代器
vec.end();//返回向量中最后一个元素的下一个位置的迭代器,仅作结束游标,不可解引用
vec.rbegin();//返回一个反向迭代器,该迭代器指向容器的最后一个元素
vec.rend();//返回一个反向迭代器,该迭代器指向容器第一个元素前面的位置

·元素的添加

vec.push_back(x);//把x插入到向量的尾部
vec.insert(iter,x);//在迭代器iter指向的元素之前插入值为x的新元素,返回指向新插入元素的迭代器
vec.insert(iter,n,x);//在迭代器iter指向的元素之前插入n个值为x的新元素,返回void
vec.insert(iter,start,end);//把迭代器start和end所指定的范围内的所有元素插入到迭代器iter所指元素之前,返回void

·元素的删除

vec.clear();//删除所有元素
vec.pop_back();//删除向量尾部的元素
vec.erase(iter);//删除迭代器iter所指向的元素,返回一个迭代器,指向被删除元素后面的元素
vec.erase(start,end);//删除迭代器start、end所指定范围内的元素,返回一个迭代器,指向被删除元素段后面的元素
vec.remove(m);//删除元素m

·其他

vec.swap(vec2);//交换两个向量的内容
vec.reverse();//反转元素顺序
  1. STL list(双向链表)的使用
    ·使用前应包含头文件和命名空间:
#include <list>
using namespace std::list

在这里插入图片描述
·创建和初始化:

list<int> lst1;//默认构造函数,lst1为空
list<int> lst2(size);//lst2初始化为size个元素,默认值是0
list<int> lst3(size,value);//lst3初始化为size个值为value的链表
list<int> lst4(lst3);//lst4是lst3的一个副本
list<int> lst5(iter1,iter2);//用迭代器iter1和iter2之间的元素创建lst5
list<int> lst6{1,2,3,4,5,6,7};//lst6用列表初始化

·容量和大小

auto length = lst.size();
lst.empty();//若链表为空则返回true
lst.resize(n);//将长度改为n,超出的元素被删除
lst.resize(n,m);//长度改为n,超出的元素设为m

·元素的访问

//list无法使用索引访问
lst.front();//返回链表中第一个元素的引用
lst.back();//返回链表中最后一个元素的引用
lst.begin();//返回链表中第一个元素的迭代器
lst.end();//返回链表中最后一个元素的下一个位置的迭代器,仅作结束游标,不可解引用
lst.rbegin();//返回一个反向迭代器,该迭代器指向容器的最后一个元素
lst.rend();//返回一个反向迭代器,该迭代器指向容器第一个元素前面的位置

·元素的添加

lst.push_front(x);//把x插入到链表的头部
lst.push_back(x);//把x插入到链表的尾部
lst.insert(iter,x);//在迭代器iter指向的元素之前插入值为x的新元素,返回指向新插入元素的迭代器
lst.insert(iter,n,x);//在迭代器iter指向的元素之前插入n个值为x的新元素,返回void
lst.insert(iter,start,end);//把迭代器start和end所指定的范围内的所有元素插入到迭代器iter所指元素之前,返回void

·元素的删除

lst.clear();//删除所有元素
lst.pop_back();//删除链表头部的元素
lst.pop_back();//删除链表尾部的元素
lst.erase(iter);//删除迭代器iter所指向的元素,返回一个迭代器,指向被删除元素后面的元素
lst.erase(start,end);//删除迭代器start、end所指定范围内的元素,返回一个迭代器,指向被删除元素段后面的元素
lst.remove(m);//删除元素m
lstt.unique();//删除连续重复元素

·其他

lst.swap(lst2);//交换两个链表的内容
lst.reverse();//反转元素顺序
  1. 线性表的链式存储结构
    ·头指针:链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。无论链表是否为空,头指针均不为空。头指针是链表的必要元素。
    ·头结点:放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度)。有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其它结点的操作就统一了。头结点不一定是链表必须要素。

  2. 单链表结构和顺序存储结构的时间性能对比
    ·查找:顺序存储结构O(1)、单链表O(n)。
    ·插入和删除:顺序存储结构需要平均移动表长一半的元素,时间为O(n);单链表在线出某位置的指针后,插入和删除时间仅为O(1)。

  3. 静态链表:用数组描述的链表。
    数组的元素都是由两个数据域组成,data和cur。数组的每个下标都对应一个data和一个cur。数据域data,用来存放数据元素;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。

  4. 循环链表:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表。

  5. 双向链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域。故双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。

发布了12 篇原创文章 · 获赞 0 · 访问量 128

猜你喜欢

转载自blog.csdn.net/weixin_43279709/article/details/104769827
今日推荐