线性表分为
-
链表
- list:链表(内存不一定连续,不可以通过下标访问,方便添加删除)
-
顺序表
- vector:顺序表(内存连续,可以通过下标访问,方便随机访问),可变大小的动态数组
- 添加元素:
push_back()/insert() - 删除元素:
pop_back()/erase()/clear() - 访问元素:
front()/back()/at()/[]/begin()/end()等
面试题
删除顺序表中的某个元素,与链表效率相同:把要删除的元素的值和最后一个元素交换,然后删除最后一个元素(无序情况下)
Vector代码实现
Vector.h
#pragma once
#include <iostream>
#include "Iterator.h"
class Vector {
public:
//Vector();//默认构造函数
Vector(int count = 2);
//默认析构函数
~Vector();
//拷贝构造函数
Vector(const Vector& vec);
//添加一个元素
void push_back(const int& val);
//移出最后一个元素
void pop_back();
//返回第一个元素
int& front();
//返回最后一个元素
int& back();
//返回容器大小
int getSize() const {
return size;
}
//重载下标运算符
int& operator[](int index) const;
//重载赋值运算符
Vector& operator=(const Vector&);
//判断是否为空
bool empty() const {
return size <= 0;
}
private:
//判断是否已满
inline bool full() const {
return size == maxSize;
}
//扩容函数
void expansion();
//返回容器最大值
int getMaxSize() const {
return maxSize;
}
public:
//迭代器:begin/end/erase/insert
Iterator begin()const;//返回指向第一个元素的迭代器
Iterator end()const;//返回指向最后一个元素下一个的迭代器
Iterator erase(Iterator currentIt);//参数是当前迭代器,返回值是指向删除的最后一个元素的下一位置的迭代器
Iterator erase(Iterator startIt, Iterator endIt);//参数是一个区间
Iterator insert(Iterator currentIt, const int &val);//第一个参数是当前迭代器,第二个参数是插入的值
void insert(Iterator currentIt, int num, const int &val);
private:
int *data;//省钱堆区连续的内存:首地址
int size;//元素个数
int maxSize;//最大容量
};
Vector.cpp
#include "Vector.h"
#include <string>
#include <iostream>
//默认申请2个大小的内存
Vector::Vector(int count):data(new int[count]),size(0),maxSize(count) {
}
Vector::~Vector() {
delete[] data;
data = nullptr;
}
/*
重载下标运算符
*/
int& Vector::operator[](int index) const {
if (index >= 0 && index < size) {
return data[index];
} else {
std::runtime_error err("下标越界");
throw err;
}
}
/*
重载赋值运算符
*/
Vector& Vector::operator=(const Vector& vec) {
Vector temp(vec);
return temp;
}
/*
拷贝构造函数
*/
Vector::Vector(const Vector& vec) {
this->maxSize = vec.getMaxSize();
this->size = vec.getSize();
data = new int[maxSize];
for (int i = 0; i < vec.getSize(); i++) {
data[i] = vec.data[i];
}
}
/*
动态增容
*/
void Vector::expansion() {
//改变容量
maxSize *= 2;
//1.申请原先大小2倍的内存
int *temp = new int[maxSize];
//2.将就内存中的内容拷贝到新内存中
//拷贝内存函数 1.目的地址, 2.原地址 3.拷贝的内存字节数
memcpy(temp, data, size * sizeof(int));
//3.释放就内存
delete[] data;
//4.data指向新内存
data = temp;
}
/*
插入一个元素
*/
void Vector::push_back(const int& val) {
//判断容器是否满了
if (full()) {
expansion();
}
data[size++] = val;
}
/*
移出最后一个元素
*/
void Vector::pop_back() {
if (!empty()) {
size--;
} else {
std::runtime_error err("容器为空,操作异常");
throw err;
}
}
/*
返回最第一个元素
*/
int& Vector::front() {
if (size > 0) {
return data[0];
} else {
std::runtime_error err("容器为空,操作异常");
throw err;
}
}
/*
返回最后一个元素
*/
int& Vector::back() {
if (size > 0) {
return data[size - 1];
} else {
std::runtime_error err("容器为空,操作异常");
throw err;
}
}
/*
返回迭代器起始位置
*/
Iterator Vector::begin()const {
return Iterator(data);
}
/*
返回迭代器末尾位置
*/
Iterator Vector::end()const {
return Iterator(data + size);
}
/*
根据当前迭代器位置删除值
*/
Iterator Vector::erase(Iterator currentIt) {
Iterator it(data);
int i = 0;
while ((it + i++) != currentIt);
for (int j = i; j < size - 1; j++) {
data[j] = data[j + 1];
}
size--;
return Iterator(data + i);
}
/*
删除一个区间
*/
Iterator Vector::erase(Iterator startIt, Iterator endIt) {
Iterator it = startIt;
int count = 0;
do {
it = erase(it);
count++;
} while (it != (endIt - count));
return it;
}
/*
在指定位置currentIt前插入值为val的元素,返回指向这个元素的迭代器
*/
Iterator Vector::insert(Iterator currentIt, const int &val) {
//添加前先判断是否满了
if (full()) {
expansion();
}
Iterator it(data);
int i = -1;
//根据迭代器找到对应的下标
while ((it + ++i) != currentIt);
for (int j = size; j >= i; j--) {
data[j] = data[j - 1];
}
data[i] = val;
size++;
//返回迭代器对象
return Iterator(data + i);
}
/*
在指定位置currentIt前插入num个值为val的元素
*/
void Vector::insert(Iterator currentIt, int num, const int &val) {
while (num-- > 0) {
currentIt = insert(currentIt, val);
}
}
迭代器
迭代器:类似于指针,指向某一个元素:
- 数据成员
- 四大默认成员函数
- 成员函数
- 自增自减++/--
- *:去内容
- ==/!=
- +/-
- ->
Iterator.h
class Iterator {
public:
Iterator(int* element = nullptr);
~Iterator();
//重载赋值运算符
//Iterator& operator=(const Iterator& it);
//前置++:先自增再运算(返回本身)
Iterator& operator++();
//后置++:先运算再自增(返回没有自增之前的临时变量)
Iterator operator++(int);
//前置--:
Iterator& operator--();
//后置--:
Iterator operator--(int);
//重载*运算符
int& operator*() const;
//常引用的作用:防止调用拷贝构造函数,提高效率
//重载!=运算符
bool operator!=(const Iterator &it)const;
//重载==运算符
bool operator==(const Iterator &it)const;
//重载+运算符
Iterator operator+(int index)const;
//重载-运算符
Iterator operator-(int index)const;
private:
int* element;
};
IIrator.cpp
#include "Iterator.h"
#include <assert.h>
#include <string.h>
Iterator::Iterator(int* element):element(element) {
}
Iterator::~Iterator(){
element = nullptr;
}
//前置++
Iterator& Iterator::operator++() {
this->element++;
return *this;
}
//后置++
Iterator Iterator::operator++(int val) {
Iterator temp = *this;
this->element++;
return temp;
}
//前置--:
Iterator& Iterator::operator--() {
this->element--;
return *this;
}
//后置--:
Iterator Iterator::operator--(int) {
Iterator temp = *this;
this->element--;
return temp;
}
int& Iterator::operator*() const {
return *element;
}
bool Iterator::operator!=(const Iterator &it)const {
return element != it.element;
}
bool Iterator::operator==(const Iterator &it)const {
return element == it.element;
}
Iterator Iterator::operator+(int index)const {
//设置断言判断不为空
assert(element + index != nullptr);
return Iterator(element + index);
//return *this;
}
Iterator Iterator::operator-(int index)const {
assert(element - index != nullptr);
return Iterator(element - index);
}
//Iterator& Iterator::operator=(const Iterator& it) {
// int count = 0;
// while ((it + count++) != nullptr);
// // 避免自赋值
// if (this != &it) {
// // 避免内存泄露
// if (element != nullptr) {
// delete[] element;
// element = nullptr;
// }
// element = new int[count];
// memcpy(element, it.element, count * sizeof(int));
// }
//
// return *this;
//}