PTA 6-2 顺序表操作集 (20 分)-容易做错

综述:

        该题为数据结构顺序表基本操作相关的题目,其中包括插入、寻找、删除以及创建线性表共4个要求,题目给了函数接口的定义,要求你写相关函数,我开始在做这个题的时候对这个题的意思有了点误解,题目说Last保存最后一个元素的位置,然后它要开MAXSIZE个int大小的空间,因为这个Last的描述我开始忽略了顺序表的特性,让我难受了好久。本篇博客大致讲解一下该题目的做法。


目录

综述:

题目:

函数接口定义: 

裁判测试程序样例:

 输入样例:

输出样例: 

函数接口1-创建线性表:

创建线性表代码-List MakeEmpty():

函数接口2-寻找指定的元素:

寻找指定元素代码-Position Find(List L, ElementType X) :

函数接口3-在指定位置插入元素: 

指定位置插入元素的代码-bool Insert(List L, ElementType X, Position P):

函数接口4-删除指定位置元素: 

删除指定位置元素代码-bool Delete(List L, Position P):

总结: 


题目:

        本题要求实现顺序表的操作集。

函数接口定义: 

List MakeEmpty(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

其中List结构定义如下:

 typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

各个操作函数的定义为:

List MakeEmpty():创建并返回一个空的线性表;

Position Find( List L, ElementType X ):返回线性表中X的位置。若找不到则返回ERROR;

bool Insert( List L, ElementType X, Position P ):将X插入在位置P并返回true。若空间已满,则打印“FULL”并返回false;如果参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false;

bool Delete( List L, Position P ):将位置P的元素删除并返回true。若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 5
#define ERROR -1
typedef enum {false, true} bool;
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

List MakeEmpty(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        if ( Insert(L, X, 0)==false )
            printf(" Insertion Error: %d is not in.\n", X);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
            printf("%d is at position %d.\n", X, P);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &P);
        if ( Delete(L, P)==false )
            printf(" Deletion Error.\n");
        if ( Insert(L, 0, P)==false )
            printf(" Insertion Error: 0 is not in.\n");
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

 输入样例:

6
1 2 3 4 5 6
3
6 5 1
2
-1 6

输出样例: 

FULL Insertion Error: 6 is not in.
Finding Error: 6 is not in.
5 is at position 0.
1 is at position 4.
POSITION -1 EMPTY Deletion Error.
FULL Insertion Error: 0 is not in.
POSITION 6 EMPTY Deletion Error.
FULL Insertion Error: 0 is not in.


函数接口1-创建线性表:

        这个部分是这道题最简单的部分,malloc一下就OK,但是有个地方还是需要注意的,因为题目说Last是线性表最后一个元素的位置,对应的也就是数组的下标,为什么我在代码里将Last的初始值设置成-1呢?是因为在第一次插入元素时该元素的下标为0,-1加加就是0,这样后面写插入函数啥的都方便一些。

创建线性表代码-List MakeEmpty():

List MakeEmpty()
{
    List p = (List)malloc(sizeof(struct LNode));
    p->Last = -1;
    return p;
}

函数接口2-寻找指定的元素:

        这一块也没啥好说的,就是遍历到顺序表的最后一个元素,如果在之前找到了元素,就返回下标,如果遍历完都没找到,就返回ERROR

寻找指定元素代码-Position Find(List L, ElementType X) :


函数接口3-在指定位置插入元素: 

        插入这个部分还是要好好说说的,首先插入元素的时候插入的位置得要合规吧,空间满了也不能插入呀,那么这里首先是不是要需要两个判定条件呀?

        这两个条件具体点就是:

第一、插入的元素个数不能超过MAXSIZE

第二、插入的位置可以在顺序表的第一个元素的前面插入-头插,也可以在最后一个元素的后面一个地方插入-尾插。当然你必须也能够在中间插入。

        满足了插入条件后的位置P是不是就要具体插入到顺序表里了?那么具体该如何操作呢?--具体看下图~

 

        上图便是插入大概逻辑,当然这算是在中间插入的情况我们整体代码的逻辑能不能满足在Last后面插入还有在最开始的地方插入呢? 答案是当然可以-整体逻辑不变具体看下面代码~

指定位置插入元素的代码-bool Insert(List L, ElementType X, Position P):

bool Insert(List L, ElementType X, Position P)
{
    if (L->Last >= MAXSIZE-1)
    {
        printf("FULL");
        return false;
    }
    else if (P < 0 || P > L->Last+1)
    {
        printf("ILLEGAL POSITION");
        return false;
    }
    else
    {
        int pr = L->Last + 1;
        while (pr > P)
        {
            L->Data[pr] = L->Data[pr - 1];
            pr--;
        }
        L->Data[pr] = X;
        L->Last++;
        return true;

    }
}

函数接口4-删除指定位置元素: 

        删除元素和插入元素是很有异曲同工之妙的,同样的在我们删除前需要判断删除的位置到底合不合理,同样的也是有相应的条件。

        删除元素的位置肯定是在位置0到位置Last中的某个元素[0,Last],其他位置没有有效的数据,所以在这个范围之外的元素就直接返回false。

        位置判断合理的元素就要开始删除它了,如何删除呢?具体操作还是看下图~

        上图便是删除的大概逻辑,当然这算是在中间位置删除的情况,那同样的我们整体代码的逻辑能不能满足在头删和尾删呢? 答案是当然可以-整体逻辑不变具体看下面代码~

删除指定位置元素代码-bool Delete(List L, Position P):

bool Delete(List L, Position P)
{
    if (P < 0 || P>L->Last)
    {
        printf("POSITION %d EMPTY", P);
        return false;
    }
    else
    {
        int pr = P;
        while (pr < L->Last)
        {
            L->Data[pr] = L->Data[pr + 1];
            pr++;
        }
        L->Last--;
        return true;
    }
        
}

总结: 

        常规顺序表操作题,题不难,但是题罗里吧嗦容易看花眼,然后测试用例感觉给的也不大好,调试的时候感觉非常麻烦,建议调试的时候直接删除它的测试代码,直接调用接口更容易测试,最后想说的是顺序表听起来很简单,但是不管听起来多简单,你不上手实际敲一遍你可不能说你懂了,大家在学习中还是多敲多练多调试,可不敢说听懂了就是会了。

                                                                                        共勉~

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

芝士就是菜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值