列表
c++可以使用动态数组来实现列表,就当复习一下vector吧(std::list也可以)
1.定义
#include<iostream>
#include<vector>
using namespace std;
vector<int> nums1;
vector<int> nums = { 1, 2, 3, 4, 5 };
2.因为本质是数组,所以访问元素与数组相同
3.插入与删除元素
vector的pushback类似于python中的append
我将遍历也写上去了,记住vector的几个内置函数
vector.clear() //清空数组
vector.push_back() //从列表最后加入数
vector.begin() //返回一个迭代器,指向数组中的第一个元素
vector.size() //计算数组大小
vector.insert(vector.begin()+i, number) //插入元素
vector.erase(vector.begin()+i)//清除元素
该动态数组类似于列表,区别于普通数组,他在插入和删除后会自动调整数组中其它元素的标签和位置。
nums.clear();
nums.push_back(1);
nums.push_back(3);
nums.push_back(2);
nums.push_back(5);
nums.push_back(4);
for (int i = 0; i < nums.size(); i++)
{
cout << nums[i] << endl;
}
cout << endl;
nums.insert(nums.begin() + 3, 6);
for (int i = 0; i < nums.size(); i++)
{
cout << nums[i] << endl;
}
cout << endl;
nums.erase(nums.begin() + 3);
for (int i = 0; i < nums.size(); i++)
{
cout << nums[i] << endl;
}
4.遍历列表
vector类似于python的遍历形式 int num:nums让我想起了for num in nums
int count = 0;
for (int num : nums)
{
count += num;
}
5.拼接列表
vector<int> nums1 = { 6,8,7,10,9 };
nums.insert(nums.end(), nums1.begin(), nums1.end());
6.排序列表
#include<algorithm>
sort(nums.begin(), nums.end());
7.不用vector实现列表
#include<iostream>
#include"vector"
using namespace std;
class MyList {
private:int* arr;
int arrCapacity = 10; //列表容量
int arrSize = 0; //当前元素数量
int extendRatio = 2; //每次列表扩容的倍数
public:
MyList() {
arr = new int[arrCapacity];
}
~MyList() {
delete[] arr;
}
int size() {
return arrSize;
}
int capacity() {
return arrCapacity;
}
int get(int index) {
if (index < 0 || index >= size())
throw std::out_of_range("索引越界");
return arr[index];
}
void set(int index, int num) {
if (index < 0 || index >= size())
throw std::out_of_range("索引越界");
arr[index] = num;
}
void add(int num) {
if(size() == capacity())
extendCapacity();
arr[size()] = num;
arrSize++;
}
void insert(int index, int num) {
if (index < 0 || index >= size())
throw std::out_of_range("索引越界");
if (size() == capacity())
extendCapacity();
for (int j = size() - 1; j >= index; j--)
{
arr[j + 1] = arr[j];
}
arr[index] = num;
arrSize++;
}
int remove(int index){
if (index < 0 || index >= size())
throw std::out_of_range("索引越界");
int num = arr[index];
for (int j = index; j < size() - 1; j++)
{
arr[j] = arr[j + 1];
}
arrSize--;
return num;
}
void extendCapacity() {
int newCapacity = capacity() * extendRatio;
int* tmp = arr;
arr = new int[newCapacity];
for (int i = 0; i < size(); i++)
{
arr[i] = tmp[i];
}
delete[] tmp;
arrCapacity = newCapacity;
}
vector<int> toVector() {
vector<int> vec(size());
for (int i = 0; i < size(); i++)
{
vec[i] = arr[i];
}
return vec;
}
};
内存与缓存
1.计算机中的存储设备
硬盘用于长期存储大量数据,内存用于临时存储程序运行中正在处理的数据,而缓存则用于存储经常访问的数据和指令。
在程序运行时,数据会从硬盘中被读取到内存中,供CPU计算使用。缓存可以看作CPU的一部分,它通过智能地从内存加载数据,给CPU提供高速的数据读取,从而显著提升程序的执行效率,减少对较慢的内存的依赖。
2.内存空间利用方面的内存效率
1)内存是有限的,且同一块内存不能被多个程序共享。
数组不需要额外的空间来存储链表节点间的指针,因此内存效率更高,但数组需要一次性分配足够的连续内存空间,这可能导致内存浪费;
2)减少内存碎片化程序,链表由于是分散存储,导致内存中的连续空间越来越少。
3.缓存效率
1)缓存未命中,即CPU尝试访问的数据不在缓存中,因此需要提高缓存命中率;
2)缓存的机制:# 缓存行:不是单个字节地存储,而是以行为单位;
# 预取机制: 预测访问模式
# 空间局部性:缓存某一数据,也会加载其附加的数据
# 时间局部性:数据多次访问可能性
综上:数组在多数情况下是优于列表的,但仍要视具体情况而定