【吉大刘大有数据结构绿皮书】已知长度为n的线性表A采用顺序存储结构,写一算法,删除该线性表中所有值为item的数据元素。

本文介绍了如何优化线性表顺序存储结构中删除指定值元素的算法,从最初的双层循环实现的O(n^2)复杂度,改进为单层循环的O(n)复杂度。通过设置移动计数器,避免了重复的元素移动,提高了效率。同时提供了完整的C语言代码实现和测试案例。
摘要由CSDN通过智能技术生成

题目

已知长度为n的线性表A采用顺序存储结构,写一算法,删除该线性表中所有值为item的数据元素。

思路及解答

题目要求A时顺序表,并删除值为item的元素,一般的想法是遍历整个顺序表,每次遍历遇到值为item的元素后,就将后面的元素依次向前移动一格,保证值为item的元素所占内存被覆盖,间接删除,其C语言实现如下:

//删除顺序表中值为item的数据元素
void DeleteSeqList1(SeqList* A, int item)
{
    int n = A->len;//顺序表长度
    for (int i = 0; i < n; i++)
    {
        //找到要删除的元素后,将后面的元素依次向前移动
        if (A->data[i] == item)
        {
            //写到n-1避免越界
            for (int j = i; j < n-1; j++)
            {
                A->data[j] = A->data[j + 1];
            }
            A->len--;
        }
    }
}

由上述代码的双层循环可知,其算法时间复杂度明显为 O ( n 2 ) O(n^{2}) O(n2),如果考试要求事件复杂度较好的情况下完成这个算法,那么上面这个函数的时间复杂度很糟糕,我们要想办法换成时间复杂度更好的算法,尽量用一次循环就解决问题,设置变量m(初值为0)用于记录被删除元素的个数,n为顺序表的长度,如果循环遍历满足删除的条件,则让m=m+1,否则就让删除元素后面的元素依次向前移动m个内存单位(即data[i-m]=data[i],其算法的过程图示如下(已知顺序表(1,2,3,4,5,6,3,7),要删除的元素是3):
1
2
3
4
其对应的C语言代码如下:

//删除顺序表中值为item的数据元素
void DeleteSeqList(SeqList* A, int item)
{
    int n = A->len;//变量n是顺序表的长度
    int m = 0;//变量m记录了删除元素的个数,当删除后,每次循环时,都要将前面的元素向前移动m个格子确保删除
    for (int i = 0; i < n; i++)
    {
        if (A->data[i] == item)
        {
            m = m + 1;
        }
        else
        {
            A->data[i - m] = A->data[i];//删了多少元素,就将非删除的元素向前移动多少,保证没有空缺
        }
    }
    A->len = n - m;
}

由此可见,这种方法更好,因为它的算法时间复杂度为 O ( n ) O(n) O(n)
完整的测试代码如下:

#include <stdio.h>
#include<stdlib.h>
#define MaxSize 1000
//顺序存储结构的线性表
typedef struct SeqList {
    int len;//顺序表长度
    int data[MaxSize];//顺序存储结构
}SeqList;
//初始化
void InitSeqList(SeqList* L)
{
    L->len = 0;
}
//在下标为index的位置插入元素elem
void InsertSeqList(SeqList* L, int index, int elem)
{
    if (index<0 && index>L->len)
    {
        printf("下标越界!\n");
        return;
    }
    L->data[index] = elem;
    L->len++;
}
//尾插
void InsertTailSeqList(SeqList* L, int elem)
{
    if (L->len > MaxSize)
    {
        printf("已超过顺序表最大容量,无法插入!\n");
        return;
    }
    L->data[L->len] = elem;
    L->len++;
}
//打印顺序表
void printSeqList(SeqList* L)
{
    if (L->len == 0)
    {
        printf("顺序表空!\n");
    }
    for (int i = 0; i < L->len; i++)
    {
        printf("%d\t", L->data[i]);
    }
    printf("\n");
}
//删除顺序表中值为item的数据元素O(n)
void DeleteSeqList(SeqList* A, int item)
{
    int n = A->len;//变量n是顺序表的长度
    int m = 0;//变量m记录了删除元素的个数,当删除后,每次循环时,都要将前面的元素向前移动m个格子确保删除
    for (int i = 0; i < n; i++)
    {
        if (A->data[i] == item)
        {
            m = m + 1;
        }
        else
        {
            A->data[i - m] = A->data[i];//删了多少元素,就将非删除的元素向前移动多少,保证没有空缺
        }
    }
    A->len = n - m;
}
//删除顺序表中值为item的数据元素O(n^2)
void DeleteSeqList1(SeqList* A, int item)
{
    int n = A->len;//顺序表长度
    for (int i = 0; i < n; i++)
    {
        //找到要删除的元素后,将后面的元素依次向前移动
        if (A->data[i] == item)
        {
            //写到n-1避免越界
            for (int j = i; j < n-1; j++)
            {
                A->data[j] = A->data[j + 1];
            }
            A->len--;
        }
    }
}
int main()
{
    SeqList* L = (SeqList*)malloc(sizeof(SeqList));
    if (L == NULL)
    {
        printf("内存不足!\n");
        return 0;
    }
    InitSeqList(L);
    InsertTailSeqList(L, 1);
    InsertTailSeqList(L, 2);
    InsertTailSeqList(L, 3);
    InsertTailSeqList(L, 4);
    InsertTailSeqList(L, 5);
    InsertTailSeqList(L, 6);
    InsertTailSeqList(L, 3);
    InsertTailSeqList(L, 7);
    printSeqList(L);
    DeleteSeqList(L, 3);
    printSeqList(L);
    return 0;
}

测试结果

测试结果

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔理沙偷走了BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值