一、顺序表的定义
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续存储单元依次存储数据元素的线性结构。线性表才用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
二、顺序表的存储结构
将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构,顺序表采用的便是顺序结构。
在顺序结构中,假设每个元素占用的空间大小是X个字节,第一个单元的存储地址我们成为基地址,把它写为LOC(a1),那么在存储结构中任意节点ai 的存储地址便可通过下面的公式得到:
LOC(ai) =LOC(a1) + X * (i-1)
在顺序表中,每个结点的存储地址是该节点在表中位置i的线性函数。只要知道基地址和每个元素所占空间大小,那么便可得到任意结点的存储地址,这是一种随机存储结构。
三、顺序表的操作
顺序表的操作有构造空表,销毁顺序表,增加元素,删除元素……我们通过一个例子来说明它所有的操作:
#include<stdio.h>
#include<malloc.h>
#include<windows.h>
#define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
#define LISTINCREAMENT 10 //顺序表存储空间分配增量
typedef struct
{
int *elem; //存储空间的基地址
int length; //顺序表当前长度
int listsize; //当前分配的存储大小
}sqlist;
void InitList(sqlist &L) //目的是为了构建一个空表
{
L.elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
if(!L.elem) //分配空间失败
exit(0);
L.length = 0;
L.listsize = LIST_INIT_SIZE;
}
void AgainMalloc(sqlist &L) //空间不够的时候重新分配空间大小
{
int *newbase;
newbase = (int *)realloc(L.elem, (L.listsize + LISTINCREAMENT)*sizeof(int));
L.elem = newbase;
L.listsize += LISTINCREAMENT;
}
void DestroyList(sqlist &L) //目的是为了销毁线性表
{
if(L.elem)
free(L.elem);
}
void ClearList(sqlist &L) //将线性表重置为空表
{
L.length = 0;
}
void InsertLast(sqlist &L, int a) //向表尾插入元素
{
if(L.length >= L.listsize)
AgainMalloc(L);
L.elem[L.length] = a;
L.length++;
}
void InsertFirst(sqlist &L, int a) //向表头插入元素
{
if(L.length >= L.listsize)
AgainMalloc(L);
for(int i=L.length-1;i>=0;i--)
L.elem[i+1] = L.elem[i];
L.elem[0] = a;
L.length++;
}
bool ListEmpty(sqlist &L) //若是空表,返回true
{
if(L.length==0)
return true;
return false;
}
int ListLength(sqlist &L) //返回L中元素的个数
{
return L.length;
}
void GetElem(sqlist &L, int i, int &e) //用e返回L中第i个元素的值
{
e = L.elem[i-1];
}
void ListInsert(sqlist &L, int i, int a) //在第i个位置之前插入新的元素e
{
if(L.length >= L.listsize)
AgainMalloc(L);
for(int j=L.length-1;j>=i-1;j--)
L.elem[j+1] = L.elem[j];
L.elem[i-1] = a;
L.length++;
}
void ListDelete(sqlist &L, int i, int e) //删除L的第i个元素,用e返回其值
{
e = L.elem[i-1];
for(int j=i-1;j<L.length;j++)
L.elem[j] = L.elem[j+1];
L.length--;
}
int Search(sqlist &L, int e) //查找给出元素的位置
{
for(int i=0;i<L.length; i++)
if(L.elem[i] == e)
return i+1;
}
void Inverse(sqlist &L) //顺序表的逆置
{
int low = 0, high = L.length-1;
int a;
for(int i=0;i<L.length/2;i++)
{
a = L.elem[low];
L.elem[low++] = L.elem[high];
L.elem[high--] = a;
}
}
void Print(sqlist &L) //遍历整个顺序表,并全部输出元素
{
for(int i=0;i<L.length;i++)
printf("%d ", L.elem[i]);
printf("\n");
}
int main()
{
sqlist L;
InitList(L);
int n, e;
printf("请输入你想要输入顺序表元素的个数,之后输入元素\n");
scanf("%d", &n);
for(int i=0;i<n;i++)
{
int a;
scanf("%d", &a);
InsertLast(L, a);
}
//向表头插入一个元素0
InsertFirst(L, 0);
//返回第i个元素的值
int i = 3;
GetElem(L, i, e);
printf("%d\n", e);
//在第i个元素为之前插入一个0
ListInsert(L, i, 0);
// ListDelete(L, i, e);
Print(L);
Inverse(L);
Print(L);
ClearList(L);
Print(L);
DestroyList(L);
return 0;
}
这里我自己写了顺序表操作的一些代码,那么接下来我便说说顺序的 优点 :
顺序表的存储密度高,它是连续存储的,那么我们便可以对它进行随机访问,方便查找元素。
那么它的缺点是什么:
它的缺点很显而易见,在当我向顺序表表首插入元素的时候,它需要移动整个顺序表,效率很低
如果我们需要大量的访问元素,元素的数量不是特别多,而且对元素的增加删除操作不是很多,那么顺序表肯定是你的第一选择!