一、顺序表的概念
顺序表是一种线性的数据结构,又属于线性表的一种,其中数据元素按照特定顺序依次存储在连续的内空间中,它由一系列元素组成,每一个元素都与唯一索引(下标)相关联,索引从0开始递增。
二、顺序表的搭建
先用#definev eletype 数据类型,这样便于修改变量的数据类型;然后定义一个结构体(struct sequentialList ),在结构体中,先定义一个指针(eletype* elements),用于存储顺序表的元素,再定义一个顺序表的存储元素个数(int size),和顺序表的容量(int capacity),顺序表实际容量 size<=capacity;
#include<iostream>
using namespace std;
#define eletype int
struct sequentialList {
eletype* elements;//存储的数组,用指针表示
int size;//顺序表中元素个数
int capacity;//顺序表实际容量 size<=capacity
};
然后进行一个初始化,为结构体中的变量进行赋初值;
void intializeList(sequentialList* list, int capacity) {
list->elements = new eletype[capacity];//为elements申请capacity个空间
list->size = 0;
list->capacity = capacity;
}
再进行顺序表的销毁
void distroyList(sequentialList* list) {
delete[] list->elements;
}
获取元素个数接口(获取顺序表大小)
int size(sequentialList* list) {
return list->size;
}
以及最后判断顺序表是否为空
//判断顺序表是否为空
bool isEmpty(sequentialList* list) {
return list->size == 0;
}
三、顺序表的组成
所有的数据结构都由增删改查四个部分组成。
1、顺序表的元素插入
顺序表的元素插入,就是按照给定索引和一个元素,将这个元素插入到对应的索引位置上,这个位置以后的元素都要往后移动一个位置。
元素插入步骤:
第一步:判断插入位置是否合法(throw std::invalid_argument("Invalid index")),不合法就抛出异常(例如:原本只有5个元素,给定的索引是10,或者是给定下标小于0,那么给定的位置就是不合法的);
//1、判断插入位置是否合法
if (index<0 || index>list->size) {
throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
}
第二步:如果顺序表位置已满,那么就需要扩容顺序表,将原来的顺序表的容量进行倍增,要注意的是,进行完扩容后,要将原来空间中的元素重新赋给新的空间,并将原来空间内存进行销毁(delete[]);
//2、当顺序表空间用完之后,进行扩容
if (list->size == list->capacity) {
int newcapacity = list->capacity * 2;//定义一个新的空间为原来空间的两倍
eletype* newelements = new eletype[newcapacity];//将新定义的空间赋给一个新的指针
//将原来数组中元素赋给新的数组
for (int i = 0; i < list->size; ++i) {
newelements[i]=list->elements[i];
}
delete[] list->elements;//将原来数组内存删除
list->capacity = newcapacity;
list->elements = newelements;
}
第三步:将插入位置之后的元素往后移动,为新元素腾出空间,要注意的是(插入时是从最后一个位置往前遍历,并且将后一个元素传递给前一个位置);
//插入元素
for (int i = list->size; i > index; i--) {
list->elements[i] = list->elements[i - 1];
}
第四步:将新元素插到指定位置;
list->elements[index] = element;
第五步:更新顺序表的大小,顺序表大小加一。
list->size++;
2、元素的删除
顺序表的元素删除,就是指定一个索引,将这个索引上的元素删除,并且把这个索引位置后面的所有元素都往前移动一个位置。
元素删除步骤:
第一步:与元素的插入相同都需要进行判断位置是否合法,这里判断的是删除位置是否合法,与元素插入不同的是,删除所判断的位置区间为0到size-1,当位置为size时元素不存在;
//判断删除位置是否合法
if (index<0 || index>=list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
}
第二步:当删除位置为最后一个位置时,直接将顺序表的大小减一;
第三步:如果删除位置不是最后一个元素,将删除位置之后的元素向前移动,覆盖要删除的元素;
//删除元素
for (int i = index; i < list->size - 1; ++i) {
list->elements[i] = list->elements[i + 1];
}
list->size--;
第四步:更新顺序表的大小。
3、元素的查找
顺序表的元素查找是指在顺序表中查找指定元素是否存在,如果存在则返回该元素索引,否则返回-1。
查找步骤:
第一步:遍历整个顺序表,对顺序表中每个元素,和指定元素进行比较,如果相同则返回当前索引;
for (int i = 0; i < list->size; ++i) {
if (list->elements[i] == element) {
return i;
}
}
第二步:如果遍历完整个顺序表元素都没有找到相同元素,便返回-1(return-1;)。
4、元素的索引
顺序表的元素索引,是指给定一个索引值,通过下标访问,直接在顺序表中获取元素的值。
索引的步骤只有一步:直接通过索引访问即可得到对应的元素,但是在索引访问前要进行判断是否合法,和删除操作相同。
eletype getElemnets(sequentialList* list, int index) {
//判断索引位置是否合法
if (index < 0 || index >= list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
}
return list->elements[index];
}
5、元素的修改
顺序表的元素修改是指将顺序表中指定元素更新为新的值。
修改步骤与索引步骤相同都需要进行判断位置是否合法,然后直接通过索引访问即可得到对应元素,修改成指定的值。
void updateElement(sequentialList* list, int index, eletype value) {
//判断修改位置是否合法
if (index < 0 || index >= list->size) {//0到list->size-1为数组空间,当index为list->size时元素不存在
throw std::invalid_argument("Invalid index");//抛出异常;表示下标非法
}
list->elements[index] = value;//修改值
}
四、顺序表的使用
int main() {
sequentialList mylist;
intializeList(&mylist, 10);
for (int i = 0; i < 10; ++i) {
insert(&mylist, i, i * 10);
}
cout << "size: " << size(&mylist) << endl;
cout << "is empty: " << isEmpty(&mylist) << endl;
//元素索引
for (int i = 0; i < size(&mylist); ++i) {
//元素插入
cout << getElemnets(&mylist, i)<<" ";
}
cout << endl;
//元素修改
int idx = findElement(&mylist, 20);
updateElement(&mylist,idx, 21);
for (int i = 0; i < size(&mylist); ++i) {
cout << getElemnets(&mylist, i)<<" ";
}
cout << endl;
//元素删除
deleteElement(&mylist, 3);//删除索引为3上的数:30
updateElement(&mylist, 1, 12);
for (int i = 0; i < size(&mylist); ++i) {
cout << getElemnets(&mylist, i) << " ";
}
cout << endl;
distroyList(&mylist);//销毁顺序表
return 0;
}