前言
本文参考张乃孝老师的《数据结构与算法》,使用头歌的习题。
一、什么是顺序表
通常线性表可以采用顺序储存和链式储存两种储存方式。采用顺序储存是表示线性表的最简单方式,即将线性表中的元素一个接一个地存储在一片相邻的存储区域中。这种顺序表示的线性表也称为顺序表。
二、存储结构
顺序线性表数据结构定义
typedef int DataType;
struct seqList
{
int MAXNUM;//顺序栈中最大元素的个数
int n;//存放线性表中元素的个数n<=MAXNUM
DataType *element;//element[0],element[1],...,element[n-1]存放线性表中的元素
}
typedef struct seqList *PseqList;
三、c语言实现顺序表
创建空顺序线性表
//创建一个空的顺序线性表,能存放的最大元素个数为m
PseqList createNullList_seq(int m)
{
PseqList palist = (PseqList)malloc(sizeof(struct seqList));
if(m == 0)return NULL;
if(palist != NULL)
{
palist->element = (DataType*)malloc(sizeof(DataType)*m);
if(palist->element)
{
palist->MAXNUM = m;
palist->n = 0;//空表长度为0
return palist;
}
}
printf("Out of space!!\n");//存储分配失败
return NULL;
}
顺序线性表插入
在顺序线性表中下标为p位置、p位置之前、p位置之后插入数据元素
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
int isFullList_seq(PseqList L)
{
if(L->n == L->MAXNUM)return 1;
else return 0;
}
在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
如果线性表满了, 还需输"list is full"的提示
如果插入位置非法,需输出提示"position is illegel"
int insertP_seq(PseqList L,int p,int x)
{
int q;
// if(isFullList_seq(L))
// {
// printf("list is full");
// return 0;
// }
if(L->n >= L->MAXNUM)//溢出
{
printf("list is full");
return 0;
}
if(p<0 || p>L->n)//不存在下标为p的元素
{
printf("position is illegel");
return 0;
}
for(q=L->n-1;q>=p;q--)
{
L->element[q+1] = L->element[q];
L->element[p] = x;
L->n = L->n+1;
return 1;
}
}
在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
提示:直接调用insertP函数实现即可
int insertPre_seq(PseqList L , int p ,int x)
{
if(insertP_seq(L , p-1 , x))
return 1;
else
return 0;
}
在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
提示:直接调用insertP函数实现即可
int insertPost_seq(PseqList L , int p ,int x)
{
if(insertP_seq(L , p+1 , x))
return 1;
else
return 0;
}
逐个输出线性表的元素,相邻的两个数据元素之间以一个空格为分隔符隔开
void printList_seq(PseqList L)
{
int i;
for(i=0;i<L->n;i++)
{
printf("%d ",L->element[i]);
}
}
销毁线性表
返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
int destroyList_seq(PseqList L)
{
if(!L) return 0;
int q;
q = L->n;
free(L->element);
L->element = NULL;//避免出现野指针
return q;
}
顺序线性表的查找
(1)在顺序线性表中查找第一个值为x的元素下标。
int locate_seq(PseqList L,int x)
{
int q;
for(q=0;q<L->n;q++)
L->element[q]==x)
return q;
return -1;
}
(2)在顺序线性表中查找某个位置pos处的数据元素
DataType locatePos_seq(PseqList L,int pos)
{
int q;
for(q=0;q<L->n;q++)
if(q==pos)
return L->element[q];
return L->element[0];
}
顺序线性表的删除
(1)在顺序表L中删除下标pos处的数据元素
//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
int deletePos_seq(PseqList L,int pos)
{
int q;
if(pos<0 || pos>L->n-1)//不存在下标为pos的元素
{
printf("Not exist!\n");
return 0;
}
for(q=pos;q<L->n-1;q++)
L->element[q] = L->element[q+1];//被删除元素之后的元素均前移一个位置
L->n = L->n-1;//元素个数减1
return 1;
}
(2)在顺序表L中删除与参数x值相同的数据元素
//在顺序表L中删除与参数x值相同的数据元素,返回删除数据元素的个数
int delete_seq(PseqList L,int x)
{
int p;
int flag=0;
while(locate_seq(L,x)!=-1)
{
p = locate_seq(L,x);
deletePos_seq(L,p);
flag+=1;
}
return flag;
}
顺序表的应用
(1)使用将顺序表L中值为x的数据元素替换为y;
void replace_seq(PseqList L,int x,int y)
{
int q;
for(q=0;q<L->curNum;q++)
if(L->element[q]==x)
L->element[q]=y;
return 0;
}
(2)此处假设线性表中的元素用于表示集合,不考虑线性表中元素的位置,移除线性表中的所有重复元素;不要使用额外的数组空间,必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
void delDuplicate_seq(PseqList L)
{
for(int i=0;i<L->curNum-1;i++)
{
delete_seq(L,L->element[i]);
}
}
四、总结
写这篇文章是为了复习这学期最开始学习的顺序表,让忘记的结构和代码重新回到我的脑袋中,顺序表操作十分简单,但对于删除、添加元素的时候,平均需要移动n/2次,极其浪费,可以说没有完美的结构,只有适合的结构!