在数据结构中,我们最开始接触的就是顺序表,那么顺序表是什么呢?顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
既然它有数组的特点,又具有线性这一特征,那么最基本的增、删、查、改、逆置肯定是必须掌握的,今天我们来盘点一下怎样对顺序表中的元素进行增删查改和逆置。
函数原型:
void InitSeqList(PSeqList seq); //初始化顺序表
void PushBack(PSeqList pSeqList, DataType data); //尾插法插入元素
void PopBack(PSeqList pSeqList); //尾插法移出元素
void PushFront(PSeqList pSepList, DataType data); //头插法插入元素
void PopFront(PSeqList pSeqList); //头插法移出元素
void Insert(PSeqList pSeqList, int pos, DataType data); //任意位置插入元素
void Erase(PSeqList pSeqList, int pos); //删除指定位置的元素
int Find(PSeqList pSeqList, DataType data); //查找元素
void Remove(PSeqList PseqList, DataType data); //删除指定元素
int Empty(PSeqList pSeqList); //判满
void PrintSeqList(PSeqList pSeqList); //打印顺序表
void Inverse(PSeqList pSeqList); //逆置顺序表
void Change(PSeqList pSeqList,DataType data1,DataType data2); //将顺序表中指定元素进行修改
源代码如下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
#define MAX_SIZE 10
typedef int DataType;
typedef struct SeqList
{
DataType array[MAX_SIZE];
int size;
}SeqList,*PSeqList;
void InitSeqList(PSeqList seq) //初始化顺序表
{
memset(seq->array,0,MAX_SIZE*(sizeof(DataType)));
seq->size=0;
}
int Empty(PSeqList seq) //判满
{
if(seq->size > MAX_SIZE)
return 1;
else return 0;
}
void PushBack(PSeqList seq, DataType data) //尾插法插入元素
{
assert(seq); //设置断言,检测是否为空
if(Empty(seq))
{
return;
}
seq->array[seq->size]=data;
seq->size++;
}
void PopBack(PSeqList seq) //尾插法删除元素
{
assert(seq);
if(Empty(seq))
{
return;
}
--seq->size;
}
void PushFront(PSeqList seq, DataType data) //头插法插入元素
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=seq->size;i>0;i--)
{
seq->array[i]=seq->array[i-1];
}
seq->array[0]=data;
seq->size++;
}
void PopFront(PSeqList seq) //头插法删除元素
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<seq->size-1;i++)
{
seq->array[i]=seq->array[i+1];
}
--seq->size;
}
void Insert(PSeqList seq, int pos, DataType data) //任意位置插入元素
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=seq->size;i>pos;i--)
{
seq->array[i]=seq->array[i-1];
}
seq->array[pos]=data;
seq->size++;
}
void Erase(PSeqList seq, int pos) //删除任意位置元素
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=pos;i<seq->size;i++)
{
seq->array[i]=seq->array[i+1];
}
--seq->size;
}
int Find(PSeqList seq, DataType data) //在顺序表中查找元素
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<seq->size;i++)
{
if(seq->array[i]==data)
{
printf("%d在顺序表的第%d位置\n",data,i+1);
return;
}
}
printf("顺序表中不存在该元素!\n");
return;
}
void Remove(PSeqList seq, DataType data) //在顺序表中删除给定元素
{
int j=0;
int i=0;
int ret=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<seq->size;i++)
{
if(seq->array[i]==data)
{
for(j=i;j<seq->size-1;j++)
{
seq->array[j]=seq->array[j+1];
}
--seq->size;
return;
}
}
printf("%d不存在!\n",data);
}
void PrintSeqList(PSeqList seq) //打印顺序表
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<seq->size;i++)
{
printf("%d ",seq->array[i]);
}
printf("\n");
}
void Inverse(PSeqList seq) //顺序表的逆置
{
int i=0;
int temp=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<(seq->size)/2;i++)
{
temp=seq->array[i];
seq->array[i]=seq->array[seq->size-1-i];
seq->array[seq->size-1-i]=temp;
}
}
void Change(PSeqList seq,DataType data1,DataType data2) //将顺序表中指定元素进行修改
{
int i=0;
assert(seq);
if(Empty(seq))
{
return;
}
for(i=0;i<seq->size;i++)
{
if(seq->array[i]==data1)
{
seq->array[i]=data2;
return;
}
}
printf("%d不存在!\n",data1);
}
测试函数:
void text()
{
SeqList seq;
InitSeqList(&seq); //初始化
PrintSeqList(&seq);
PushBack(&seq,1);
PushBack(&seq,2);
PushBack(&seq,3);
PushBack(&seq,4);
PushBack(&seq,5);
PushBack(&seq,6);
PushBack(&seq,7); //尾插法插入元素
PrintSeqList(&seq);
PopBack(&seq); //尾插法移出元素
PrintSeqList(&seq);
PushFront(&seq,8);
PushFront(&seq,9); //头插法插入元素
PrintSeqList(&seq);
PopFront(&seq); //头插法移出元素
PrintSeqList(&seq);
Insert(&seq,3,10); //插入元素
PrintSeqList(&seq);
Erase(&seq,3); //删除元素
PrintSeqList(&seq);
Inverse(&seq); //逆置
PrintSeqList(&seq);
Find(&seq,9); //查找
PrintSeqList(&seq);
Remove(&seq,9); //删除指定元素
PrintSeqList(&seq);
Change(&seq,9,2); //修改指定元素
PrintSeqList(&seq);
}
int main()
{
text();
system("pause");
return 0;
}
在这里我们可以对顺序表做一个总结:
- 实现方法简单。在很多高级语言中都有数组类型,总体是比较容易实现的。
- 每个元素的存储位置可以用一个简单的公式来计算。
- 查找和打印操作都以线性的时间来执行,移出元素花费的时间比较固定。所以非常适合于那些需要经常进行查找操作的情况。
- 顺序存储的空间是静态分配的,需要事先指定MAX_SIZE的大小。也因此可能会造成空间的浪费。
- 插入和删除的代价非常高昂,这两种操作在最坏的情况下的时间复杂度为O(n),平均估计这两种操作需要移动一半的元素。
在顺序表中插入或者删除一个元素,是非常复杂的,它需要把元素一个一个移动,然后插入或者删除。所以在顺序表做插入或删除是很浪费的行为,平均每个结点移动的次数约为表长的一半,时间复杂度相对而言也比较高。如果建立的模型有太多需要插入删除的元素,是否选用顺序表就需要综合考虑了。