12-线性表顺序存储的应用

  在介绍了线性表的顺序存储结构和基本运算的实现后,我们可以根据这种实现的思维来解决相关的应用问题,比如删除元素,通过一个例子来说明。

例1——删除元素

问题:已知长度为n的线性表A采用顺序存储结构,设计算法,删除线性表中所有值为x的数据元素。

要求:时间复杂度为O(n)、空间复杂度为O(1)的算法





第一种解法用基本运算来实现,代码如下:

void Remove_node(SqList* sqlist , int element)
{
    if(NULL == sqlist)
    {
        return;
    }
    //pos记录要删除的元素下标索引
    int pos;
    //通过Select_List查找要删除的元素element,并返回该元素的位置pos
    while((pos = Select_List(sqlist, element)) >= 0)
    {
         //然后根据位置pos删除元素
        RemoveByPos_List(sqlist , pos);
    }
}

  对于这个算法来说, Remove_node操作在删除元素时还要去循环移动元素的位置,所以它的时间复杂度为O(n2)、空间复杂度为O(1),而我们的要求是时间复杂度为O(n),显然这个算法的时间复杂度不符合要求。

  在这个删除元素的例子中,我们需要明白一点:在实际解决问题中,很多情况下我们用同样的思维方式去考虑问题,但是不一定用所有的基本运算组合起来去解决问题,因为有时候这样去做的话,并不能很好的解决一些问题。因此应该根据实际的情况选择合适的算法,而并不是一味地去用基本运算

  在这一篇中,我们不仅要学习删除元素的算法,还有删除元素的算法背后解决问题的过程和思维方式,这也是我们需要学习并磨练的地方。

  数据结构本身是一门灵活性非常强的学科,因此我们在学习已有的知识的基础上,应该多加思考,尽量去扩展自己的思维,也就是说,当我们面对一个问题的时候,能做到举一反三,在提出一个解法时,应该思考一下:是否还有更好的解法。



因此我们可以用第二种解法,复制要保留的元素:

这里写图片描述
图2-第二种解法

  假设现在我们要删除线性表L中所有为2的数据元素,那么可以通过复制要保留的元素依次保存到线性表L1中,也就是说对于要删除的所有为2的数据元素,不要复制到线性表L1中。在这里实际上L和L1之间是共享存储空间的,因此算法的时间复杂度为O(n),空间复杂度为O(1)。

第二种解法的思想:
  1.逐个复制要保留的元素
  2.要点:L1和L共用空间,即不需要额外空间



第二种解法的具体实现代码:

//x为要删除的数据元素
void Remove_node2(SqList* sqlist , int element)
{

    //size记录非x的元素个数
    int size = 0;
    int i;
    for(i = 0; i < sqlist->length; i++)
    {   
        //把不重复的数据元素复制到顺序表L1中
        if(sqlist->DataAddr[i] != element)
        {
            sqlist->DataAddr[size] = sqlist->DataAddr[i];
            size++;
        }
    }
    //然后把不重复的元素个数赋值给length
    sqlist->length = size;
}

测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include "sqlist.h"

int main(void)
{   
    //初始化顺序表
    SqList *sqlist = Init_List();
    int i;
    for(i = 0; i < 6; i++)
    {
        if(i % 2 == 0)
        {
            Insert_Element_List(sqlist,2);
            continue;
        }
        Insert_Element_List(sqlist,i);
    }
    printf("------------打印全部元素---------------\n");
    //打印全部的元素
    Print_List(sqlist);
    printf("------------删除所有值为2的元素-----------\n");
    //第一种解法
    //Remove_node(sqlist, 2);
    //第二种解法
    Remove_node2(sqlist, 2);
    Print_List(sqlist);
    return 0;
}

测试结果:
这里写图片描述

从测试的结果来看,第二种解法同样能达到第一种解法的效果,同时还能降低时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值