列表是一个抽象的数据结构概念,它表示元素的有序集合,并且支持增删改查,无须考虑容量。链表、数组都可以看作列表。长度不可变的列表实用性会变低,因此很多编程语言的列表都是基于动态数组实现。

列表常用操作

初始化列表

vector<int> nums1;
vector<int> nums = {1, 2, 3, 4, 5};

访问元素和更新元素

int num = nums[1];
nums[1] = 0;

插入与删除元素

nums.clear();
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);

nums.insert(nums.begin() + 3, 6);

nums.erase(nums.begin() + 3);

遍历列表

int count = 0;
for (int i = 0; i < nums.size(); ++i) {
  count += nums[i];
}

count = 0;
for (int num : nums) {
  count += num;
}

拼接列表

vector<int> nums1 = {6, 7, 8, 9, 10};
nums.insert(nums.end(), nms1.begin(), nums2.begin());

排序列表

sort(nums.begin(), nums.end());

列表实现

列表主要有三个重点设计:

  • 初始容量。数组根据初始的最大元素数量申请对应的内存空间。
  • 元素数量。使用变量size记录当前元素数量。
  • 扩容机制。插入元素时容量已满,则需要扩容。
class MyList {
private:
  int* arr;
  int arrCapacity = 10;
  int arrSize = 0;
  int extendRatio = 2; // 扩容因子
  
public:
  MyList() {
    arr = new int[arrCapactiy];
  }
  
  ~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];
  }
  
  int set(int index, int num) {
    if (index < 0 || index >= size()) throw out_of_range("索引越界");
    arr[index] = num;
  }
  
  void add(int num) {
    if (size() == capacity())
      extentdCapacity();
    arr[size()] = num; 
    ++arrSize;
  }
  
  int remove(int index) {
    if (index < 0 || index >= size()) throw out_of_range("索引越界");
    int num = arr[index];
    
    for(int i = index; i < size(); ++i) {
      arr[i] = arr[i + 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;
  }
}