线性表:(
linear list )是n个
具有相同特性的数据元素的有限序列 。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:
顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线 。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
什么是顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构 ,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表代码实现
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表
#pragma once
#include <iostream>
#include <cassert>
namespace ns_Seq{
template <class T>
class SeqList{
private:
T* arr;
int size;
int capacity;
public:
SeqList()
:arr(nullptr)
,size(0)
,capacity(0)
{}
private:
void CheckCapacity(){
if(size >= capacity){
T newCapacity = capacity == 0 ? 4 : 2 * capacity;
T* newArr = new T[newCapacity];
if (arr) {
for (int i = 0; i < size; ++i) {
newArr[i] = arr[i];
}
}
delete [] arr;
arr = newArr ;
capacity = newCapacity;
}
}
public:
void insert(size_t pos,const T& val){
CheckCapacity();
assert(pos >= 0 && pos <= size);
for (int i = size; i > pos; --i) {
arr[i] = arr[i - 1];
}
arr[pos] = val;
size++;
}
void erase(size_t pos){
assert(pos >= 0 && pos <= size);
assert(size > 0);
for(int i = pos; i < size-1; ++i){
arr[i] = arr[i+1];
}
size--;
}
void push_back(const T& val){
insert(size,val);
}
void pop_back(){
erase(size);
}
void push_front(const T& val){
insert(0,val);
}
void pop_front(){
erase(0);
}
int find(const T& val){
for(int i = 0; i < size; ++i){
if(arr[i] == val){
return i;
}
}
return -1;
}
void printSeq(){
for(int i = 0; i < size; i++){
std::cout<< arr[i] << " ";
}
std::cout<<std::endl;
}
public:
~SeqList(){
delete [] arr;
size = 0;
capacity = 0;
}
};
}
顺序表问题
- 中间/头部的插入删除,
时间复杂度 为O(N) - 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
- 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间
|