数据结构之列表

列表

列表是一个抽象的数据结构概念,它表示元素的有序集合,支持元素的访问,修改,添加,删除和遍历等操作。无需使用着考虑容量限制的问题,列表的实现可以基于数组或者链表。

列表的常用操作

初始化列表

#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零壹学府,每日分享自己的学习经验

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零壹寻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值