数据结构当中最常见的就是线性表,线性表的储存结构有顺序表和链表之分,这次就让我们来认识下线性表的两种储存结构
顺序表的存储结构简单来说就是以数组的方式来存储
优点:
- 可以随机存取,快速定位到表中需要存取的位置
- 存储密度高,只存储数据
缺点:
- 规定的存储空间有限,需要后期优化扩容;
- 删除和添加表中的元素时需要移动大量的元素,因此删除操作多时更多的使用链表;
- 造成存储的碎片化
顺序表的定义:顺序表的定义只需要定义出一个数组和表示顺序表的长度就行了 。同时顺序表的空间的分配可以采取静态分配和动态分配两种 如下
- 静态分配
#include <cstring>
#include <iostream>
#define maxsize 2
using namespace std;
struct TypeElem
{
string name;
int age;
};
#define MAXSIZE 100 //定义最大长度
typedef struct {
TypeElem Elem[MAXSIZE]; //用静态数组存放数据元素
int length; //顺序表的当前长度
}OrderTable; //顺序表名称
void InitalOrderTable(OrderTable& O){
O.length = 0;
}
- 动态分配
#define maxsize 10
typedef struct {
TypeElem* elem; //用静态数组存放数据元素
int length; //顺序表的当前长度
}OrderTable; //顺序表名称
void InitialOrderTable (OrderTable &O){
O.elem = new TypeElem[maxsize]; //动态分配空间
if( !O.elem) exit(OVERFLOW)
O.length = 0;
}
顺序表的各种实现方式
插入元素
bool Insert(OrderTable& O, int n, int j) {
if (n<1 || n>O.length + 1) {
return false; //判断添加位置是否合理
}if (O.MAXSIZE <= O.length ) {
cout << "存储空间满" << endl; //判断空间是否满了
return false;
}
else
{
for (int i = n-1; i <O.length; i++)
{
O.elem[i+1] = O.elem[i]; //将每个n后面的元素后移一位
}
cin >> O.elem[n-1].name >> O.elem[n-1].age;
O.length++;
return true;
}
}
删除元素
bool ODelete(OrderTable& O, int n, TypeElem e) {
if (!O.elem) {
return false; //判断表是否为空
}if (n<1 || n>O.length) {
return false; //判断删除的位置是否合理
}
e = O.elem[n - 1];
for (int i = n-1; i < O.length; i++)
{
O.elem[i] = O.elem[i + 1]; //将删除元素后的元素依次都前移一位
}
O.length--;
return true;
}
按值查找
int OGet(OrderTable& O, TypeElem e) {
for (int i = 0; i < O.length; i++)
{
if (O.elem[i] == e) {
return i+1;
}
}return 0; //没有找到
}
以上就是对顺序表基本操作的讲解和分析,其实在顺序表操作中,只要理解了顺序表的创建,后面的增删改查其实都很容易理解。在学习数据结构与算法的过程中,我们更多的是要去思考代码如何实现,操作的整个流程是怎样的,这样有助于我们牢记重点和知识点,并且学起来也不会很枯燥。同样,我也会持续更新数据结构与算法的内容,在自我提升的同时,也能有好的内容分享给大家