目录
1.数组
1.1 基本形式:
char a[100]; //数组的基本形式
1.2 动态内存数组:
int n; //指示数组大小
char* a = nullptr; //定义数组起始
cin>>n; //定义数组大小
a = new char[n]; //给数组a开辟相应的内存(在堆区)
... //对数组进行自己需要的操作
delete [] a; //用完之后,需要释放内存
a = nullptr; //指针置空
与数组的区别是,向量在定义完之后,大小可以动态变化。(本质还是数组,只是关于数组的一些复杂操作,都经过封装,变为了一些简单的函数直接呈现给我们了)
2.向量
2.1 基本形式:
#include<vector>
//使用vector需要的头文件
vector<char> v = {'h', 'e', 'l', 'l', 'o'};
v[0] = 'b';
//向量中元素的访问及修改方法与数组相同
v.push_back('s');
//该函数可以使向量增长,在向量的末尾添加‘s’
v.pop_back();
//可删除最后一个元素
v.erase(v.begin()+1);
//删除中间的元素,此处,是删除下表为一的元素,即删除‘e’,并且,该函数在删除元素后,会让之后的元素向前挪动,填补空缺,时间复杂度为O(n),所以,不常使用。
2.2 关于向量的大小与容量:
vector<char> v(100);
cout << v.size(); //print'100' 大小
cout << v.capacity(); //print'100' 容量
v.push_back('x');
cout << v.size(); //print'101' 大小
cout << v.capacity(); //print'200' 容量
向量的内部是数组,初始数组大小(a1[100])是100,在超出最大容量之后,就会进行扩容,生成一个更大的数组(a2[200]),在将初始数组按顺序复制进去,在将超出的内容依次放入新的数组中,之后,将初始数组(a1[100])释放掉。
由于,上文的操作较为费时,所以每次扩容时,都会建立一个超大的数组,经过前辈们的计算,每次新数组容量为旧数组的两倍时,最为节省时间,所以,容量是成倍增长的。
3.链表(双向)
#include<list> //使用list<>的头文件
list<char> l = {'h', 'e', 'l', 'l', 'o'}; //建立一个字符型双向链表
//链表有两个指针(front、back),一个指示头部,一个指示尾部
//以下两个函数可访问头部与尾部的函数
cout << l.front(); //print 'h'
cout << l.back(); //print 'o'
//访问链表中部,因为链表的特殊性,要想访问链表的中间部分,只能通过遍历链表的方法进行
list<char>::iterator iter = l.begin();
//iter为变量名,该变量为一个指针,初始指示头部,可用来访问中部链表元素
cout << *iter; //print 'h'
iter++; //是iter指向下一个节点
cout << *iter; //print 'e'
*iter = 'a'; //如此会将链表中的‘e’变为‘a’
//链表插入
l.push_back('s'); //插入到链表的末尾
l.push_front('a'); //插入到链表的头部
//时间复杂度为O(1),此为链表优于数组的地方
//链表删除
l.pop_back(); //删除结尾节点
l.pop_front(); //删除头部节点