PTA6-5 链式表操作集

PTA6-5 链式表操作集

本题要求实现链式表的操作集。

函数接口定义:

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

其中List结构定义如下:

typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

各个操作函数定义为:
Position Find( List L, ElementType X ):返回线性表中首次出现X的位置。若找不到则返回ERROR;
List Insert( List L, ElementType X, Position P ):将X插入在位置P指向的结点之前,返回链表的表头。如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回ERROR;
List Delete( List L, Position P ):将位置P的元素删除并返回链表的表头。若参数P指向非法位置,则打印“Wrong Position for Deletion”并返回ERROR。

裁判测试程序样例:

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

#define ERROR NULL
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

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

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

    L = NULL;
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        L = Insert(L, X, L);
        if ( L==ERROR ) printf("Wrong Answer\n");
    }
    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 {
            L = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( L==ERROR )
                printf("Wrong Answer or Empty List.\n");
        }
    }
    L = Insert(L, X, NULL);
    if ( L==ERROR ) printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    tmp = Insert(L, X, P);
    if ( tmp!=ERROR ) printf("Wrong Answer\n");
    tmp = Delete(L, P);
    if ( tmp!=ERROR ) printf("Wrong Answer\n");
    for ( P=L; P; P = P->Next ) printf("%d ", P->Data);
    return 0;
}

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

输入样例:

6
12 2 4 87 10 2
4
2 12 87 5

输出样例:

2 is found and deleted.
12 is found and deleted.
87 is found and deleted.
Finding Error: 5 is not in.
5 is inserted as the last element.
Wrong Position for Insertion
Wrong Position for Deletion
10 4 2 5

AC代码:

Position Find(List L,ElementType X)
{
    while(L)
    {
       if(L->Data==X)
       {
          return L;
       }
       L=L->Next;
    }
    return ERROR;
}

List Insert(List L,ElementType X,Position P)
{
   List q1,q2;
   if(P==L)
   {
      q1=(List)malloc(sizeof(List));
      q1->Data=X;
      q1->Next=L;
      L=q1;
      return L;
   }
   q1=L;
   while(q1)
   {
      if(q1->Next==P)
      {
         q2=(List)malloc(sizeof(List));
         q2->Data=X;
         q2->Next=q1->Next;
         q1->Next=q2;
         return L;
      }
      q1=q1->Next;
   }
   printf("Wrong Position for Insertion\n");
   return ERROR;
}
List Delete(List L,Position P)
{
   List q1=L;
   if(P==L)
   {
      L=L->Next;
      return L;
   }
   while(q1)
   {
      if(q1->Next==P)
      {
         q1->Next=q1->Next->Next;
         return L;
      }
      q1=q1->Next;
   }
   printf("Wrong Position for Deletion\n");
   return ERROR;
}

      
<think>好的,我现在需要帮助用户解决关于PTA链式按序号查找的问题。首先,用户提供了几个参考引用,都是关于这个题目的不同解答。我需要仔细分析这些引用来找出正确的实现方法。 首先,题目要求实现一个函数,找到并返回链式的第K个元素。函数接口是ElementType FindKth(List L, int K)。根据引用中的代码,看起来不同的解答可能有细微的差别,比如是否有头结点,循环条件是否正确。 引用2中的代码使用了一个循环,count从1开始,然后循环条件是L != NULL且count < K。这里可能有错误,因为循环里用的是L,但循环内部却操作p。可能应该是检查p是否为NULL,而不是L?例如,引用4中的代码使用p = L,然后循环条件是p && i < K,这样更合理,因为L可能一开始就是NULL,即空链表的情况。 另外,引用4提到原题中没有头结点,所以L直接指向第一个节点。这点很重要,因为如果有头结点的话,需要从头结点的下一个节点开始。在用户提供的引用4的解答中,p初始化为L,即第一个节点,而没有头结点,这样处理是正确的。 接下来,循环的条件应该是p存在且计数器还没到K的位置。例如,当K=1时,直接返回p->Data。循环中,每次移动p到下一个节点,并增加计数器。如果循环结束后,p存在且计数器等于K,就返回数据,否则返回错误。 还需要注意边界条件,比如K为0或负数的情况,但题目中可能假设K是正整数。另外,当链表长度小于K时,返回ERROR。 现在需要综合这些引用中的正确部分,给出正确的实现方法。例如,正确的代码应该初始化p为L,然后循环条件是p && i < K,然后检查最终p是否存在且i等于K,否则返回错误。 在解释实现步骤时,应该分点说明,比如初始化指针、遍历链表、边界处理等。同时,要比较不同引用中的代码差异,指出可能存在的错误,如引用2中的循环条件使用L而不是p可能导致的问题。 最后,生成相关问题,可能涉及链表操作的其他函数,时间复杂度,错误处理,测试用例设计等。</think>### 链式按序号查找的实现方法 链式的按序号查找需要遍历链表直到找到第$K$个节点。以下是具体实现步骤及代码分析: --- #### **实现步骤** 1. **初始化指针** 创建指针`p`指向链表头节点(题目明确说明无头结点,`L`直接指向第一个元素) 2. **边界条件检查** -链表为空(`L == NULL`)或$K \leq 0$,直接返回错误 - 若$K=1$,直接返回头节点数据 3. **遍历链表** 使用循环移动指针,直到找到第$K$个节点: ```c while (p != NULL && count < K) { p = p->Next; count++; } ``` 4. **结果判断** - 若循环结束时`p`存在且`count == K`,返回`p->Data` - 否则返回错误值`ERROR` --- #### **完整代码实现** ```c ElementType FindKth(List L, int K) { if (L == NULL || K < 1) // 处理空链表或非法K值 return ERROR; List p = L; // 指针指向第一个有效节点 int count = 1; // 计数器从1开始 while (p != NULL && count < K) { p = p->Next; count++; } if (p != NULL && count == K) // 找到第K个节点 return p->Data; else return ERROR; } ``` --- #### **关键点说明** 1. **无头结点设计** 题目明确链式无头结点(引用4),因此直接从`L`指向的节点开始遍历[^4]。 2. **循环条件优化** 循环中需同时检查`p != NULL`和`count < K`,避免访问空指针(引用2的代码误用`L`判断可能导致逻辑错误)[^2]。 3. **时间复杂度** 最坏情况需遍历整个链表,时间复杂度为$O(n)$,符合线性操作的基本要求。 --- #### **测试用例示例** | 输入链表 | K值 | 预期输出 | |---------|-----|--------| | 1→2→3→4 | 3 | 3 | | NULL | 1 | ERROR | | 5→8 | 5 | ERROR | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值