数据结构顺序表的查找_数据结构 2.1顺序表

线性结构是数据结构中最基础、最简单的一种数据结构类型,其中最典型的就是线性表

线性表的定义

具有「相同特性」的数据元素的「有限序列」

相同特性所有元素属于同一数据类型
有限数据元素个数是有限的
序列数据元素由逻辑序号唯一确定

用逻辑序号来确定的特性使得线性表中可以有多个相同值的元素

线性表中所含元素的个数叫做线性表的长度,用n表示(n ≥ 0)

n = 0时,表示线性表是一个空表,即表中不包含任何元素

线性表的逻辑表示

线性表的逻辑表示为:

表示第个元素为逻辑位序

线性表的基本运算

  1. 初始化线性表:构造一个空的线性表l
  2. 建立线性表
  3. 销毁线性表:释放线性表l占用的内存空间
  4. 判线性表是否为空表:若为空返回1,不为空返回0
  5. 求线性表的长度:返回元素个数n
  6. 输出线性表:当线性表l不为空时,顺序输出l的每一个元素
  7. 求线性表l中指定位置的某个数据元素:用e返回l中第i个元素的值
  8. 定位查找:返回l中第一个与e相等的逻辑位序
  9. 插入一个数据元素:在l的第i个元素之前插入新的元素el的长度+1
  10. 删除数据元素:删除l的第i个元素,并用e返回其值,l的长度-1

线性表的顺序存储结构

把线性表中所有的元素按照顺序的方法进行存储。所有元素按逻辑顺序依次存储到存储器中「一片连续的存储空间」

顺序表类型定义

#define MAXSIZE 100
typedef int ElemType;
typedef struct {
    ElemType data[MAXSIZE];
    int length;
}SqList;

顺序表运算的实现

初始化线性表
void initList(SqList** l) {
    (*l) = (SqList*)malloc(sizeof(SqList));
    (*l)->length = 0;
}
建立线性表
void createList(SqList* l, ElemType a[], int n) {
    int i;
    for (i = 0; i         l->data[i] = a[i];
    }
    l->length = n;
}
销毁线性表
void destroyList(SqList* l) {
    free(l);
}
判断是否为空表
int listEmpty(SqList* l) {
    return (l->length == 0);
}
求线性表的长度
int listlength(SqList* l) {
    return (l->length);
}
当线性表不为空时,顺序显示L中各元素的值
void dispList(SqList* l) {
    int i;
    if (listEmpty(l)) {
        printf("线性表为空\n");
        return;
    }
    for (i = 0; i length; i++) {
        printf("%d ", l->data[i]);
    }
    printf("\n");
}
求某个数据元素值
int getElem(SqList* l, int i, ElemType* e) {
    if (i 1 || i > l->length) {
        return FALSE;
    }
    *e = l->data[i - 1]; //物理位序 = 逻辑位序 + 1
    return TRUE;
}

getElem()的时间复杂度为O(1)。体现了顺序表的「随机存取特性」

按元素值查找
int locateElem(SqList* l, ElemType e) {
    int i = 0;
    while (i length && l->data[i] != e) {
        i++;
    }
    if (i >= l->length) {
        return 0;
    }
    else {
        return i + 1; //返回的是逻辑位序
    }
}
插入数据元素

在插入之前,已有的元素要给新来的元素腾出空间,后面的元素都要向表尾移动一位。最后表的长度+1

4e591f865049e1e93b9eca79582b2d71.gif
在第二个位置插入元素5
int listInsert(SqList* l, int i, ElemType e) {
    int j;
    if (i 1 || i > l->length + 1) { //判断给出的下标是否合法
        return FALSE;
    }
    i--;
    for (j = l->length; j > i; j--) {
        l->data[j] = l->data[j - 1];
    }
    l->data[i] = e;
    l->length++;
    return TRUE;
}
  • i = n+1时,元素移动次数为0,最好时间复杂度为O(1)
  • i = 1时,元素移动n次,最坏时间复杂度为O(n)

线性表中有n+1个可以插入元素的地方,在插入元素ai时,若为等概率情况,则

此时需要将aian的元素均向后移动一个位置,共移动n-i+1个元素

所以在长度为n的线性表中插入一个元素时所需移动元素的平均次数为

因为插入算法主要花的时间就在移动元素上,因此插入算法的平均时间复杂度为O(n)

删除元素

用后面的元素覆盖被删除元素,同时都向表头移动。最后「表的长度-1」

bee70d062df50c243a3ade7bf5ce6070.gif
删除第二个位置的元素
int listDelete(SqList* l, int i, ElemType* e){
    int j;
    if (i 1 || i > l->length) { //判断给出的下标是否合法
        return FALSE;
    }
    i--;
    *e = l->data[i];
    for (j = i; j length - 1; j++) {
        l->data[j] = l->data[j + 1];
    }
    l->length--;
    return TRUE;
}

对于本算法来说,元素移动的次数也与表长length和删除元素的位置i有关:

  • i = n时,移动次数为0,最好时间复杂度为O(1)
  • i = 1时,移动次数为n-1,最坏时间复杂度为O(n)

在线性表l中共有n个可以删除元素的地方,在删除元素ai时,若为等概率情况,则

此时需要将a(i+1)an的元素均前移一个位置,共移动n-(i+1)+1=n-i个元素

平均时间复杂度为O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值