数据结构--线性表的顺序表示

本文详细介绍了顺序表的定义,包括静态和动态分配的实现方式,并详细阐述了线性表的基本操作,如初始化、求表长、按值查找、按位查找、插入、删除、输出、判空和销毁等操作。同时分析了各操作的时间复杂度,特别指出动态分配在空间不足时可以动态扩展。
摘要由CSDN通过智能技术生成

目录

一、顺序表的定义

二、顺序表的基本操作

1.初始化表

2.求表长

3.按值查找操作

4.按位查找操作

5.插入操作

6.删除操作

7.输出操作

8.判空操作

9.销毁操作


一、顺序表的定义

        线性表的顺序存储结构又称作线性表。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑相邻的两个元素在物理位置上也是相邻的。顺序表的特点就是:表中的元素逻辑顺序与其物理顺序相同。

首先线性表的顺序存储类型描述为:

//一维数组的静态分配
#define MaxSize 50
typedef struct{
    ElemType data[MaxSize];
    int length;
}SqList;
//初始化
SqList L;
//一维数组的动态分配
#define InitSize 50
typedef struct{
    ElemType *data;
    int length;
}SqList;
//初始化
SqList L;
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize)

 一维数组可以静态分配,也可以动态分配。

(1)在静态分配时,由于数组的大小和空间已经固定好,一旦空间占满,再加入新的数据会产生溢出,进而导致程序崩溃。

(2)在动态分配时,存储数组的空间是在程序执行过程中通过动态分配的方式,一旦数据空间占满,就另外开辟一块更大的存储空间,用以更替原来的存储空间,从而达到扩充数组空间的目的。

注意:动态分配并不是链式存储,他同样是顺序存储,物理结构没有变化,依然可以随机存储,只是分配的空间大小可以在运行时动态决定。 

二、顺序表的基本操作

1.初始化表

上面已经阐述了两种初始化表的操作:动态和静态

//动态
void InitList(&L){
    SqList L;
    L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
    L.length=0;
}
//静态
void InitList(){
    SqList L;
    L.length=0;
}

2.求表长

int Length(SqList L){
    return L.length;
}

3.按值查找操作

int LocateElem(SqList L,ElemType e){
    int i;
    for(i=0;i<L.length;i++){
        if(L.data[i]==e){
            return i+1;
        }
    }
    return 0;
}

 返回的是位序,代码里的i表示数组的下标。最好的情况下,查找的时间复杂度是O(1);最坏的情况下,查找的时间复杂度是O(n)。

4.按位查找操作

ElemType GetElem(SqList L,int i){
    return L.data[i];
}

直接返回表L中的第i个位置上的元素值,由于顺序表随机存储 的特性,时间复杂度是O(1)。

5.插入操作

bool ListInsert(SqList &L,int i,ElemType e){
    if(i<1||i>L.length+1)
        return false;
    if(L.length>=MaxSize)
        return false;
    for(int j=L.length;j>=i;j--){
        L.data[j]=L.data[j-1];
    }
    L.data[i-1]=e;
    L.length++;
    return true;
}

 前两个if语句是为了增加程序的健壮性。从最后一个元素开始直到第i个元素结束都往后移一个位置,第i个元素的数组下标为i-1所以在data[i-1]赋值为e,长度加1,插入成功返回true。时间复杂度为O(n)。

注意:在L前加&,是为了让操作在表L中实现,并不是在一个新的局部变量L操作(函数结束L也就不存在了)。

6.删除操作

bool ListDelete(SqList &L,int i,ElemType &e){
    if(i<1||i>L.length){
        return false;
    }
    e=L.data[i-1];
    for(int j=i;j<L.length;j++){
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}

 删除第i个元素(下标为i-1)先把第i个元素的值赋给e,然后把下标为i以及之后的元素往前移一位,删除成功返回true。

7.输出操作

bool PrintList(SqList L){
    for(int i=0;i<L.length;i++){
        cout<<L.data[i]<<endl;
    }
    return true;
}

8.判空操作

bool Empty(SqList L){
    if(L.length!=0){
        return true;
    }else{
        return false;
    }
}

9.销毁操作

bool DestroyList(&L){
    L.length=0;
    free(L);  //动态分配的需要用free释放内存
    //静态分配系统自动回收内存
    return true;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值