顺序线性表

前言

本文参考张乃孝老师的《数据结构与算法》,使用头歌的习题。

一、什么是顺序表

通常线性表可以采用顺序储存和链式储存两种储存方式。采用顺序储存是表示线性表的最简单方式,即将线性表中的元素一个接一个地存储在一片相邻的存储区域中。这种顺序表示的线性表也称为顺序表。

二、存储结构

顺序线性表数据结构定义

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次,极其浪费,可以说没有完美的结构,只有适合的结构!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值