列表
列表是一个抽象的数据结构概念,它表示元素的有序集合,支持元素的访问,修改,添加,删除和遍历等操作。无需使用着考虑容量限制的问题,列表的实现可以基于数组或者链表。
列表的常用操作
初始化列表
#include <iostream>
#include "vector"
using namespace std;
int main(){
//初始化列表
vector<int> num;
vector<int> nums = {1,2,3,4,5};
return 0;
}
访问元素
列表本质上是数组,因此可以在O(1)时间内访问和更新元素,效率很高
#include <iostream>
#include "vector"
using namespace std;
int main(){
//初始化列表
vector<int> num;
vector<int> nums = {1,2,3,4,5};
//访问元素
int temp = nums[1];
cout<<temp<<endl;
//更新元素
nums[1] = 520;
cout<<nums[1];
return 0;
}
//输出结果
2
520
插入与删除元素
相比于数组,列表可以自由的添加与删除元素,在列表尾部添加元素,时间复杂度为O(1),插入与删除的效率与数组一样,都是O(n)
#include <iostream>
#include "vector"
using namespace std;
int main(){
//初始化列表
vector<int> num;
vector<int> nums = {1,2,3,4,5};
//清空列表
nums.clear();
cout<<"清空列表后,列表的长度为:"<<nums.size()<<endl;
//在尾部添加元素
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(15);
cout<<"列表尾部依次添加1,2,3,15:";
cout<<"此时列表中的元素为:"<<endl;
for(int i = 0;i<nums.size();i++){
cout<<nums[i]<<" ";
}
cout<<endl;
cout<<"在索引为3出添加元素6"<<endl;
nums.insert(nums.begin()+3,6);
cout<<"此时列表中的元素为:";
for(int i = 0;i<nums.size();i++){
cout<<nums[i]<<" ";
}
cout<<endl;
cout<<"删除索引为3的元素:"<<endl;
nums.erase(nums.begin()+3);
cout<<"此时列表中的元素为:";
for(int i = 0;i<nums.size();i++){
cout<<nums[i]<<" ";
}
cout<<endl;
return 0;
}
//输出结果;
列表尾部依次添加1,2,3,15:此时列表中的元素为:
1 2 3 15
在索引为3出添加元素6
此时列表中的元素为:1 2 3 6 15
删除索引为3的元素:
此时列表中的元素为:1 2 3 15
列表的遍历
列表的遍历与数组一样,可根据索引值对列表进行遍历
#include <iostream>
#include "vector"
using namespace std;
int main(){
//初始化列表
vector<int> num;
vector<int> nums = {1,2,3,4,5};
//第一种遍历方式
for(int i = 0;i<nums.size();i++){
cout<<nums[i]<<" ";
}
cout<<endl;
//第二种遍历方式
for(int num:nums){
cout<<num<<" ";
}
return 0;
}
//输出结果
1 2 3 4 5
1 2 3 4 5
拼接列表
#include <iostream>
#include "vector"
using namespace std;
int main(){
//初始化列表
vector<int> nums = {1,2,3,4,5};
vector<int> temp = {9,8,7,6};
nums.insert(nums.end(),temp.begin(),temp.end());
for(int i : nums){
cout<<i<<" ";
}
return 0;
}
//输出结果
1 2 3 4 5 9 8 7 6
列表排序
#include <iostream>
#include "vector"
#include "algorithm"
using namespace std;
int main(){
//初始化列表
vector<int> nums = {1,2,3,4,5};
vector<int> temp = {9,8,7,6};
nums.insert(nums.end(),temp.begin(),temp.end());
cout<<"排序前:"<<endl;
for(int i : nums){
cout<<i<<" ";
}
cout<<endl;
sort(nums.begin(),nums.end());
cout<<"排序后:"<<endl;
for(int i :nums){
cout<<i<<" ";
}
return 0;
}
//输出结果
排序前:
1 2 3 4 5 9 8 7 6
排序后:
1 2 3 4 5 6 7 8 9
列表的实现
许多变成语言都内置了列表,它的实现比较复杂,如初始容量的设定,扩容的倍数等
本次列表的实现是简单的,是加深对列表工作原理的理解
- 初始容量,我们设置为10
- 数量记录,声明一个变量size用来记录当前列表的元素数量,随着列表的变化,size值也要更新。
- 扩容机制,若元素列表满了,需要扩容时,我们扩容两倍。
#include <iostream>
#include "vector"
#include "algorithm"
using namespace std;
class MyList{
private:
int *arr;//存储列表元素
int arrCapacity=10;//列表容量,默认为10
int arrSize=0;//记录当前列表中的元素个数
int extendRatio=2;//扩容倍数,默认为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 out_of_range("索引越界");
}
return arr[index];
}
//更新元素
void set(int index,int num){
//下标越界
if(index < 0 || index >= size()){
throw out_of_range("索引越界");
}
arr[index] = num;
}
/* 列表扩容 */
void extendCapacity() {
// 新建一个长度为原数组 extendRatio 倍的新数组
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;
}
//在尾部添加元素
void add(int num){
//元素数量超出容量,应该扩容
if(size() == capacity()){
extendCapacity();
}
arr[size()]= num;
arrSize++;
}
/* 在中间插入元素 */
void insert(int index, int num) {
if (index < 0 || index >= size())
throw out_of_range("索引越界");
// 元素数量超出容量时,触发扩容机制
if (size() == capacity())
extendCapacity();
// 将索引 index 以及之后的元素都向后移动一位
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 out_of_range("索引越界");
int num = arr[index];
// 将索引 index 之后的元素都向前移动一位
for (int j = index; j < size() - 1; j++) {
arr[j] = arr[j + 1];
}
// 更新元素数量
arrSize--;
// 返回被删除的元素
return num;
}
/* 将列表转换为 Vector 用于打印 */
vector<int> toVector() {
// 仅转换有效长度范围内的列表元素
vector<int> vec(size());
for (int i = 0; i < size(); i++) {
vec[i] = arr[i];
}
return vec;
}
};
int main(){
cout<<"测试自己的list"<<endl;
MyList myList;
cout<<"列表尾部添加元素1,2,3,9,8,7:"<<endl;
myList.add(1);
myList.add(2);
myList.add(3);
myList.add(9);
myList.add(8);
myList.add(7);
cout<<"将自己的列表转换为vector,打印输出:"<<endl;
vector out = myList.toVector();
for(int i :out){
cout<<i<<" ";
}
cout<<endl;
cout<<"在索引2处添加元素520:"<<endl;
myList.insert(2,520);
cout<<"将自己的列表转换为vector,打印输出:"<<endl;
out = myList.toVector();
for(int i :out){
cout<<i<<" ";
}
cout<<endl;
cout<<"删除索引为2的元素:"<<endl;
myList.remove(2);
cout<<"将自己的列表转换为vector,打印输出:"<<endl;
out = myList.toVector();
for(int i :out){
cout<<i<<" ";
}
cout<<"访问下标为3的元素:"<<endl;
int temp = myList.get(3);
cout<<"下标为3的元素是:"<<endl;
cout<<temp<<endl;
cout<<"将下标为3的元素修改为520"<<endl;
myList.set(3,520);
cout<<"下标为3的元素是:"<<myList.get(3)<<endl;
}
//测试结果
测试自己的list
列表尾部添加元素1,2,3,9,8,7:
将自己的列表转换为vector,打印输出:
1 2 3 9 8 7
在索引2处添加元素520:
将自己的列表转换为vector,打印输出:
1 2 520 3 9 8 7
删除索引为2的元素:
将自己的列表转换为vector,打印输出:
1 2 3 9 8 7 访问下标为3的元素:
下标为3的元素是:
9
将下标为3的元素修改为520
下标为3的元素是:520
关注微信公众号:IT零壹学府,每日分享自己的学习经验