前言
顺序表是一种简单的线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位元素的位置,顺序表元素与元素之间不允许有空值,进行插入、删除操作时需要移动大量元素。
一、顺序表的三个要素:
1.存储位置的基地址(elems)
2.实际元素个数,即顺序表的长度(length)
3.一段连续的存储空间(size)
如下图:
二、顺序表结构体定义及初始化
结构体的定义:
#define MAX_SIZE 100
typedef struct
{
ElemType *elems; // 顺序表的基地址(ElemType为要存储的数据类型)
int length; //顺序表的长度
int size; //顺序表总的空间大小
}Sqlist;
初始化:
bool initSqlist(Sqlist& L) //初始化顺序表(构造一个空的存储int类型数据的顺序表)
{
L.elems = new int[MAX_SIZE]; //分配 MAX_SIZE 的空间
if (!L.elems) //若动态内存分配失败,返回false,初始化失败
{
return false;
}
else
{
L.length = 0; //空表的表长为0
L.size = MAX_SIZE;
return true;
}
}
三、顺序表的"增、插、删、销"
增:给空表添加元素
插:在表中插入新的元素
删:删除表中元素
销:销毁顺序表
1.给空表添加元素
将元素添加到表尾:
bool listAppend(Sqlist& L, int e) //顺序表增加元素,e代表增加的元素
{
if (L.length == MAX_SIZE) //顺序表已满,无法在尾部添加元素
{
return false;
}
else
{
L.elems[L.length] = e; //将元素添加到表尾
L.length++; //每填一个元素,表长都要加1
return true;
}
cout << endl;
}
2.在表中插入新的元素
我们在元素"1"的位置插入元素"3"时,元素"2"先向下移动一个单位,然后元素"1"再向下移动一个位置(此时元素"1"在元素"2"移动之前的位置),最后,元素"3"再插入元素"1"移动之前的位置,这样就完成了插入新元素,每插入一个元素,表长加1(如果要在顺序表结尾插入数据,可以写一个尾插函数或者转换成在表尾添加元素进行操作)
bool listInsert(Sqlist& L, int i, int e) //i代表元素插入位置,e代表插入的元素
{
if (i < 0 || i >= L.length) //插入位置不合法
{
return false;
}
else if (L.length == MAX_SIZE) //存储空间已满,无法插入
{
return false;
}
else
{
for (int j = L.length-1; j >= i; j--)
{
L.elems[j + 1] = L.elems[j]; //元素后移,为新元素让出位置(越靠近表尾越先移动)
}
L.elems[i] = e; //元素插入
L.length++; //每插入一个元素,表长都要加1
return true;
}
}
3.删除表中元素
我们删除元素"1"时,可以直接让元素"2"向上移动一个单位,让元素"2"覆盖元素"1",然后元素"3"再向上移动一个单位,最后元素"4"向上移动一个单位,就完成了删除操作,每删除一个元素,表长减1(如果删除元素在表尾,直接让表长减1即可)
bool listDelete(Sqlist& L, int i) //删除元素,i代表删除元素的下角标
{
if (i < 0 || i >= L.length) //i值不合法,删除失败,返回false
{
return false;
}
else if (i == L.length - 1) //删除元素在表尾,表长直接减1
{
L.length--;
return false;
}
else
{
for (int j = i; j < L.length; j++)
{
L.elems[j] = L.elems[j + 1];//在表中删除元素,直接用j+1的值覆盖j的值即可
}
L.length--; //每删除一个元素,表长都要减1
return true;
}
}
4.销毁顺序表
我们在初始化顺序表时,给它分配了一块MAX_SIZE大小的内存用来存储数据,所以销毁顺序表时,只需释放掉这块内存即可
void listDestory(Sqlist& L)
{
cout << "销毁顺序表销毁..." << endl;
if (L.elems)
{
delete []L.elems; //释放内存
}
L.length = 0;
L.size = 0;
}
四、源码
#include <iostream>
#include <Windows.h>
#define MAX_SIZE 100
using namespace std;
typedef struct //构建顺序表
{
int* elems; //顺序表元素
int length; //顺序表长度
int size; //顺序表大小
}Sqlist;
bool initSqlist(Sqlist& L) //初始化顺序表
{
L.elems = new int[MAX_SIZE];
if (!L.elems) //动态内存分配失败
{
return false;
}
else
{
L.length = 0;
L.size = MAX_SIZE;
return true;
}
}
bool listAppend(Sqlist& L, int e) //顺序表增加元素,e代表增加的元素
{
if (L.length == MAX_SIZE) //顺序表已满,无法在尾部添加元素
{
return false;
}
else
{
L.elems[L.length] = e;
L.length++;
return true;
}
cout << endl;
}
bool listInsert(Sqlist& L, int i, int e) //i代表元素插入位置,e代表插入的元素
{
if (i < 0 || i >= L.length) //插入位置不合法
{
return false;
}
else if (L.length == MAX_SIZE) //存储空间已满,无法插入
{
return false;
}
else
{
for (int j = L.length-1; j >= i; j--)
{
L.elems[j + 1] = L.elems[j];
}
L.elems[i] = e;
L.length++;
return true;
}
}
bool listDelete(Sqlist& L, int i) //删除元素,i代表删除元素的下角标
{
if (i < 0 || i >= L.length) //i值不合法,删除失败
{
return false;
}
else if (i == L.length - 1)
{
L.length--;
return true;
}
else
{
for (int j = i; j < L.length; j++)
{
L.elems[j] = L.elems[j + 1];
}
L.length--;
return true;
}
}
void listDestory(Sqlist& L)
{
cout << "销毁顺序表销毁..." << endl;
if (L.elems)
{
delete []L.elems;
}
L.length = 0;
L.size = 0;
}
void listPrint(Sqlist& L) //打印顺序表信息
{
cout << endl;
cout << "顺序表内存大小 size= " << L.size
<< ", 已保存元素个数 length= " << L.length << endl;
cout << "顺序表中元素:";
for (int j = 0; j <= L.length - 1; j++)
{
cout << L.elems[j] << " ";
}
cout << endl << endl;
}
int main()
{
Sqlist L;
int i;
int e;
int count;
cout << "顺序表初始化..." << endl;
if (initSqlist(L))
{
cout << "顺序表初始化成功!" << endl;
cout << "请输入要添加的元素个数:";
cin >> count;
for (int i = 0; i < count; i++)
{
cout << "请输入要添加的元素:";
cin >> e;
if (listAppend(L, e))
{
cout << "添加成功!" << endl;
}
else
{
cout << "添加失败!" << endl;
}
}
listPrint(L);
cout << "请输入插入元素的位置:";
cin >> i;
cout << "请输入插入的元素:";
cin >> e;
if (listInsert(L, i, e))
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
listPrint(L);
cout << "请输入删除元素的角标:";
cin >> i;
if (listDelete(L, i))
{
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败!" << endl;
}
listPrint(L);
listDestory(L);
}
else
{
cout << "顺序表初始化失败!" << endl;
}
listPrint(L);
system("pause");
return 0;
}
五、运行结果
总结
以上便是对顺序表的学习总结,如有误处,请各位指正!