线性表
线性表是最简单最基本的一种数据结构,
- 一个线性表示多个具有相同类型数据串在一起
- 每个元素有前驱(前一个元素)后继(后一个元素)
- 根据不同特性
- 线性表也分为 栈 队列 链表等
一.数组(可变数组)
当数组的大小难以计算,无法确定时
在c++STL中
提供了一个可变长度数组
#include<vector>//头文件
结构 | 说明 |
---|---|
vector《int》 v(N,i) | j可变长度数组v,且初始有N个为i的元素。N,i可省略 |
v.push_back(a) | 在v的末尾插入a |
v.size() | 元素个数 |
v.resize(n,m) | 重新调整数组大小为n。如果n比原来大,则新增部分都初始化为m |
v[a] | 访问下标为a的元素 |
注意
数组越界
1.存储查询给定下标的数据:效率高,时间复杂度O(1);
2.
将整个数组的一段数据进行插入或删除
或搜索指定元素(没有排序):效率低 ,复杂度O(n)。
二.栈
特点:
- 先进后出;
- 仅允许在表的一端进行插入和删除,这一端被称为栈顶;
- 表尾端为栈顶,表头端为栈底;
栈的基本操作
-
栈的初始化
-
判空
-
判满
-
取栈顶元素
-
在栈顶进行插入和删除
在栈顶插入为入栈;
在栈顶删除元素为出栈;栈分为顺序栈和链栈
-
base 为栈底指针,始终指向栈底
-
top为栈顶指针,top的初始指向栈底,每当插入一个元素时top加1,弹出一个时top-1
-
所以 s.top=s.base;可作为栈空的标记
-
非空栈的栈顶指针始终在栈顶元素的下一个位置上 即:
base=0 | top=1 |
---|---|
base= -1 | top=0 |
- viod push(x):将x压入栈,放入元素
- viod pop()弹出栈顶元素,
- int top:查询栈顶元素;
1.数组的方式
//伪指针
//可通过改变指针的指向,来控制元素的增减
//1.push
void push(int x){
stack[p]=x;p+=1;
}
//将x赋值给stack[p],并将指针更新加一
//2.pop
void pop(){
p-=1;
//将栈顶指针后退一位
}
//3.top
int top{
return stack[p-1];
//p指的是下一个待插入的数组位置,所以,栈顶的数组位置是p-1
}
2.STL(C++中)
#include<stack>//头文件
stack<int>s//建立一个栈s,元素类型是int
s.push(a)//将元素a压入栈s
s.pop()//将 s 的栈顶元素弹出
s.top()//查询 s 的栈顶元素
s.empty() //查询 s 是否为空
s.size()//查询 s 的元素个数
三.队列
特点:
先进先出
可以在一端插入元素,另一端删除元素
队列的基本操作
void push(x);//将x压入队列,站入队尾
void pop();//弹出队首的元素,队首离开
int front;//查询队首元素
1.数组
//队列头(head)尾(tail)
void push(int x){
queue[tail]=x;
tail+=1;
}//将x赋给队尾 ,再让对尾+1
viod pop(){
head+=1;
}//头指针前进
int front(){
return queue[head];
}//直接获取q[head]
2.STL(C++)
#include<queue>//头文件
结构 | 说明 |
---|---|
queue《int》p | 建立一个队列q,其内部元素是int |
p.push(a) | 将元素a插入队列q的末尾 |
q.pop() | 将q的队首元素删除 |
q.front() | 查询q的队首元素 |
q.end | 查询q的队尾元素 |
q.size() | 查询q的元素个数 |
q.empty() | 查询q是否为空 |
使用数组时:当数组开太大,实际上队列不长,导致假溢出
可使用循环队列来映射指针,增加空间利用率当使用STL队列时不用考虑循环队列了
四.链表
链表是一种物理存储单元上非连续,非顺序的存储结构。
数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
在链表的创建中,添加一个指向下个节点的指针,
这个指针保存的是下一个节点的地址,我们说这个指针指向下一个节点。
将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向这个变量,通过指针就能找到这个变量。
特点:
链表是一种动态结构,它所占用的大小和位置是不需要提前分配的。
ins_back(x,y):将元素y插到x后面;//注意更新后继的前驱和前驱的后继
ins_front(x,y):将元素y插到x前面;
ask_back(x):询问x后面的元素;
ask_front(x):询问x后面的元素;
del(x):从表中删除元素x,不改变其他元素的先后顺序;//删除一个元素时,只需让这个元素的前驱的后继变成它后继,它后继的前驱变成他的前驱即可
种类 | 特点 |
---|---|
单向链表 | 只记录每个节点的后继。 |
双向链表 | 记录每个节点的前驱和后继 |
循环单向链表 | |
循环双向链表 | 双链表,形成环形 |
- 链表插入和删除的复杂度是 O(1)。
- 链表搜索指定元素位置/定位第k个元素的复杂度是 O(n)。
- 相比于数组,链表插入删除快,但是定位(找到第k个)慢。