线性表元素的基本操作(插入、查找和删除等)【数据结构】

本文详细介绍了线性表的插入元素(包括表头、中间和尾部)、查找元素(按值和按位)、以及删除元素的操作方法,探讨了不同操作的时间复杂度。
摘要由CSDN通过智能技术生成

上一篇我们已经说过了线性表的基本实现,包括创建线性表和遍历线性表。

线性表的基本实现快速通道:

https://blog.csdn.net/Wanghh520max/article/details/137127478

本次我们来讲述对线性表进行插入和删除元素操作。

一、顺序表插入元素

向已有顺序表中插入数据元素,根据插入位置的不同,可以分为以下 3 种情况:

  1. 插入到顺序表的表头;
  2. 在表的中间位置插入元素;
  3. 尾随顺序表中已有元素,作为顺序表中的最后一个元素;

虽然数据元素插入顺序表中的位置有所不同,但是都使用的是同一种方式去解决,

即:通过遍历,找到数据元素要插入的位置,然后做如下两步工作:

  • 将要插入位置元素以及后续的元素整体向后移动一个位置;
  • 将元素放到腾出来的位置上;

例如:在{1,2,4,5,6}的第3个位置插入元素3,实现过程如下图所示:

首先遍历线性表到指定位置,即位置3.

接下来将位置3及后面的元素依次后移,空出位置3的位置。

现在我们便可以向位置3中插入指定元素3,同时线性表的长度要动态增加一。

向线性表中插入元素的代码实现如下:

SqList *Insert_SqList_tail(SqList *L) {

    //判断此时线性表是否已满
    if (L->length >= MaxSize) {
        printf("线性表已满!");
        return 0;
    } else {
       
        int site;
        printf("请输入添加元素的位置:");     //自定义添加元素位置
        scanf("%d",&site);

        int num;                            //输入需要添加的元素
        printf("请输入需要添加的元素:");
        scanf("%d", &num);
        int i;
        for(i = L->length; i>=site; i--){
            L->data[i] = L->data[i -1];      //遍历到要插入元素的所在位置,
            }                                //并将目标位置后面的元素后移

        L->data[site - 1] =num;              //添加目标元素到线性表中

        L->length ++;                        //线性表长度增加1
    }
    return L;
}

调用主函数测试函数:

int main() {
    SqList L;
    SqList *SP;
    SP = &L;
    Init_SqList(SP);

    PrintSqList(Create_SqList(SP));        //打印当前的线性表
    PrintSqList(Insert_SqList_tail(SP));    //打印成功添加元素后的线性表
    return 0;
}

增加程序的健壮性,要是线性表长度超过MaxSzie,则无法继续插入元素。

在{1,2,4,5,6}的第3个位置插入元素3,结果如下:

二、线性表元素的查找

线性表的查找可以分为两种:按值查找和按位查找

1.按值查找

该操作是给定需要查找的元素,然后遍历线性表比较线性表中的元素是否和目标元素相等。

其时间复杂度为:

最好的情况:目标元素在表头

                        循环一次便可找到目标元素,时间复杂度为O(1)

最坏的情况:目标元素在表尾

                      需要遍历整个线性表才可找到,循环n次,时间复杂度为O(n)

平均情况:假设目标元素出现在线性表的任何一个位置的概率都相同,均是n^{-1}

     目标元素在第1位,循环1次;在第2位,循环2次;……; 在第 n 位,循环 n 次           平均复杂度为O(n)             

代码实现,我们只需遍历线性表即可。

//按值查找的代码实现
void GetElem(SqList *L) {
    int num;
    printf("请输入需要查找的元素:");
    scanf("%d", &num);
    int i;
    for (i = 0; i < L->length - 1; i++) {
        if (L->data[i] == num) {

            printf("目标元素%d排列在线性表的第%d号位置\n", num, i + 1); 
            //返回的是线性表的位置,所以返回的i值需要在数组下标的基础上加1

        }
    }
}

若找到了则返回元素所在位置。

例:在线性表{1,2,3,4,5,6,7,8}中查找元素{5}的位置

2.按位查找

由于顺序表的各个数据元素在内存中连续存放,因此可以根据起始地址和数据元素大小立即找到第 i 个元素--“随机存取”特性。

所以按位查找的时间复杂度为O(1),一次便可以找到。

代码实现,输入目标位置即可得到目标元素。

//按位查找的代码实现
void GetElem(SqList *L) {
    int site;
    printf("请输入需要查找的位置:");
    scanf("%d", &site);
    while (true) {

         //判断查找位置的合法性
        if (site < 1 || site > L->length) {
            //如果不合法则重新输入

            printf("输入位置不合法!\n请重新输入");
            printf("输入需要查找的位置:");
            scanf("%d", &site);
        } else {

            int num = L->data[site - 1];    //注意线性表和数组下标引用的区别

            printf("排列在线性表第%d号位置的元素是%d\n", site, num);
            break;
        }
    }
}

若存在则返回元素所在位置,如果输入的位置非法则给出反馈并重新输入。

例:在线性表{1,2,3,4,5,6,7,8}中查找位于第5号的元素。

健壮性测试,输入非法位置直到合法位置后查找并退出。

三、线性表的删除操作

删除表L中第i个位置的元素,并用e返回删除元素的值。

最好情况:删除表尾元素,不需要移动其他元素。i=n,循环0次;

               最好时间复杂度=0(1)

最坏情况:删除表头元素,需要将后续的n-1个元素全都向前移动i= 1,循环 n-1 次;

               最坏时间复杂度=0(n);
平均情况:假设删除任何一个元素的概率相同,即i= 1,2,3,…,length 的概率都是p=1/n;

                i=1,循环 n-1 次;i=2 时,循环 n-2 次;i=3,循环 n-3 次 …i=n 时,循环0次

                平均时间复杂度=0(n)

代码实现,此时返回指针类型,可以在main函数中打印返回以观察是否删除成功。

//线性表删除元素操作
int *DeleteSqList(SqList *L) { 
    int j;
    int site;
    printf("请输入需要删除元素的位置:");
    scanf("%d", &site);
    if (site < 1 || site > L->length) { //删除位置不合法
        return 0;
    }
    int *num = (int *) L->data[site - 1]; //接收目标位置的元素
    for (j = site + 1; j <= L->length; j++)
        L->data[j - 1] = L->data[j];

    --L->length; // 线性表的长度减少
    return num;
}

//main函数调用函数
int main() {
    SqList L;
    SqList *SP;
    SP = &L;
    Init_SqList(SP);

    PrintSqList(Create_SqList(SP));

    int *num = DeleteSqList(SP);
    if (num != 0) {
        printf("成功删除元素%d\n", num);
    } else {
        printf("删除失败!\n");
    }
    return 0;
}

例:在线性表{1,2,3,4,5,6,7,8}中删除第5号的元素.

以上便是线性表的基本操作!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值