🔥小龙报:个人主页 🎬作者简介:C++研发,嵌入式,机器人方向学习者 ❄️个人专栏:《算法通关指南》 ✨ 永远相信美好的事情即将发生
本专栏聚焦算法题实战,系统讲解算法模块:以《c++编程》,《数据结构和算法》《基础算法》《算法实战》 等几个板块以题带点,讲解思路与代码实现,帮助大家快速提升代码能力 ps:本章节题目分两部分,比较基础笔者只附上代码供大家参考,其他的笔者会附上自己的思考和讲解,希望和大家一起努力见证自己的算法成长
线性表是n 个具有相同特性的数据元素的有序序列。 线性表在逻辑上可以想象成是连续的⼀条线段,线段上有很多个点,⽐如下图:

故线性表是⼀个比较简单和基础的数据结构
线性表的顺序存储就是顺序表。 如果下图中的方格代表内存中的存储单元,那么存储顺序表中 这个元素就是放在连续的位置上:

⼤家会发现,这不就是⽤⼀个数组把这些元素存储起来了嘛?是的,顺序表就是通过数组来实现的。
PS:往后实现各种数据结构的时候,如果不做特殊说明,默认里面存储的就是int类型的数据。

//创建
const int N = 1e5 + 10; // 定义静态数组的最⼤⻓度
int a[N],n; // 直接创建⼀个⼤数组来实现顺序表, n 表⽰当前有多少个元素 //尾插
void puch_back(int x)
{
a[++n] = x; // 下标为 0 的位置空出来
// 这样操作⼀般根据个⼈习惯,也可以从 0 开始计数
// 不过有些问题从 1 计数,处理起来可以不⽤考虑边界情况
// 后续学习更深的算法的时候,就会感受到
}时间复杂度: 直接放在后⾯即可,时间复杂度为O(1)
//头插
void puch_front(int x)
{
// 要把所有的元素全部右移⼀位,然后再放到头部位置
for (int i = n; i >= 1; i--)
{
a[i + 1] = a[i];
}
a[1] = x;// 把 x 放在⾸位
n++; //不要忘记总个数 +1
}时间复杂度: 由于需要将所有元素右移⼀位,时间复杂度为O(N) 。
// 任意位置插⼊ - 在位置 p 处,插⼊⼀个 x
void insert(int x, int p)
{
for (int i = n; i >= p; i--) // 注意顺序不要颠倒
{
a[i + 1] = a[i];
}
a[p] = x;
n++; //// 不要忘记总个数 +1
}时间复杂度: 最坏情况下需要数组中所有元素右移,时间复杂度为O(N) 。
//尾删
void pop_back()
{
n--;
}时间复杂度: 显然是O(1) 。
//头删
void pop_front()
{
// 把所有元素向前移动⼀位
for (int i = 2; i <= n; i++)
{
a[i - 1] = a[i];
}
n--; // 总个数 -1
}时间复杂度: 需要所有元素整体左移,时间复杂度为O(N) 。
//任意位置删
void erase(int p)
{
//把所有元素向前移动⼀位
for (int i = p + 1; i <= n; i++)
{
a[i - 1] = a[i];
}
n--; // 总个数 -1
}时间复杂度: 最坏情况下,所有元素都需要左移,时间复杂度为O(N) 。
// 查找这个数第⼀次出现的位置,找不到返回 0
int find(int x)
{
for (int i = 1; i <= n; i++)
{
if (a[i] == x)
return i;
}
return 0;
}时间复杂度: 最坏情况下需要遍历整个数组,时间复杂度为O(N) 。
// 返回 p 位置的数
int at(int p)
{
return a[p];
}时间复杂度: 这就是顺序表随机存取的特性,只要给我⼀个下标,就能快速访问到该元素。 时间复杂度为O(1) 。
// 把 p 位置的数修改成 x
void change(int p, int x)
{
a[p] = x;
}时间复杂度: 这就是顺序表随机存取的特性,只要给我⼀个下标,就能快速访问到该元素。时间复杂度为O(1) 。
// 清空顺序表
void clear()
{
n = 0;
}时间复杂度: 要注意,我们⾃⼰实现的简单形式是O(1) 。 但是,严谨的⽅式应该是O(N) 。
#include <iostream>
using namespace std;
//创建
const int N = 1e5 + 10; // 定义静态数组的最⼤⻓度
int a[N],n; // 直接创建⼀个⼤数组来实现顺序表, n 表⽰当前有多少个元素
//打印
void print()
{
for (int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << endl;
}
//尾插
void push_back(int x)
{
a[++n] = x; // 下标为 0 的位置空出来
// 这样操作⼀般根据个⼈习惯,也可以从 0 开始计数
// 不过有些问题从 1 计数,处理起来可以不⽤考虑边界情况
// 后续学习更深的算法的时候,就会感受到
}
//头插
void push_front(int x)
{
// 要把所有的元素全部右移⼀位,然后再放到头部位置
for (int i = n; i >= 1; i--)
{
a[i + 1] = a[i];
}
a[1] = x;// 把 x 放在⾸位
n++; //不要忘记总个数 +1
}
// 任意位置插⼊ - 在位置 p 处,插⼊⼀个 x
void insert(int x, int p)
{
for (int i = n; i >= p; i--) // 注意顺序不要颠倒
{
a[i + 1] = a[i];
}
a[p] = x;
n++; //// 不要忘记总个数 +1
}
//尾删
void pop_back()
{
n--;
}
//头删
void pop_front()
{
// 把所有元素向前移动⼀位
for (int i = 2; i <= n; i++)
{
a[i - 1] = a[i];
}
n--; // 总个数 -1
}
//任意位置删
void erase(int p)
{
//把所有元素向前移动⼀位
for (int i = p + 1; i <= n; i++)
{
a[i - 1] = a[i];
}
n--; // 总个数 -1
}
// 查找这个数第⼀次出现的位置,找不到返回 0
int find(int x)
{
for (int i = 1; i <= n; i++)
{
if (a[i] == x)
return i;
}
return 0;
}
// 返回 p 位置的数
int at(int p)
{
return a[p];
}
// 把 p 位置的数修改成 x
void change(int p, int x)
{
a[p] = x;
}
// 清空顺序表
void clear()
{
n = 0;
}
int main()
{
// 测试尾插
push_back(2);
print();
push_back(5);
print();
push_back(1);
print();
push_back(3);
print();
// 测试头插
push_front(10);
print();
// 测试任意位置插⼊
insert(3, 0);
print();
//测试尾删
cout << "尾删:" << endl;
pop_back();
print();
pop_back();
print();
pop_front();
pop_front();
print();
//测试任意位置删除
cout << "任意位置删除:" << endl;
erase(3);
print();
erase(2);
print();
erase(4);
print();
for (int i = 1; i <= 10; i++)
{
cout << "查找" << i << ": ";
cout << find(i) << endl;
return 0;
}希望大家多多支持,我们下期再见!