![6c5de63a21ca0188b45099f84580bc76.png](https://img-blog.csdnimg.cn/img_convert/6c5de63a21ca0188b45099f84580bc76.png)
PTA是浙江大学设计类实验辅助教学平台。
![635806014247cd6f11c985d676b9c489.png](https://img-blog.csdnimg.cn/img_convert/635806014247cd6f11c985d676b9c489.png)
题目描述:
本题要求实现链式表的操作集。
函数接口定义:
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 Answern");
}
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 Answern");
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 Answern");
tmp = Delete(L, P);
if ( tmp!=ERROR ) printf("Wrong Answern");
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
![fbc5d8545bc5ab8a4d7d1bc3e8df3b2a.png](https://img-blog.csdnimg.cn/img_convert/fbc5d8545bc5ab8a4d7d1bc3e8df3b2a.png)
Position Find( List L, ElementType X )
:返回线性表中首次出现X的位置。若找不到则返回ERROR;
解题思路:
只需要遍历链表,判断L->Data==X。
代码如下:
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 )
:将X插入在位置P指向的结点之前,返回链表的表头。如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回ERROR;
解题思路:
首先我们需要考虑在头结点之前插入的情况。
所以,我们需要加入以下判断。
//头插
if (P==L)
{
Node->Next=L;
return Node;
}
然后我们才进行,一般的节点插入操作。
- malloc一个新节点Node
- Node->Next=L->Next
- L->Next=Node
![68186e5d0d4bff9df2be005bc896b62c.png](https://img-blog.csdnimg.cn/img_convert/68186e5d0d4bff9df2be005bc896b62c.png)
你可能还有一个问题:需要考虑在尾节点插入吗?
不需要。
题目说的是:将X插入在位置P指向的结点之前。
要在尾节点之后插入,那么P就指向非法位置了。
代码如下:
List Insert( List L, ElementType X, Position P ){
List Head=L,Node;
Node=(List)malloc(sizeof(List));
Node->Data=X;
Node->Next=NULL;
//头插
if (P==L)
{
Node->Next=L;
return Node;
}
while (L)
{
if (L->Next==P)
{
Node->Next=L->Next;
L->Next=Node;
return Head;
}
L=L->Next;
}
printf("Wrong Position for Insertionn");
return ERROR;
}
List Delete( List L, Position P )
:将位置P的元素删除并返回链表的表头。若参数P指向非法位置,则打印“Wrong Position for Deletion”并返回ERROR。
解题思路:
首先,我们同样要考虑删除的节点是头结点。
删除头结点,相当简单。
// 删除头部
if(P==L)
{
L=L->Next;
return L;
}
其余节点的删除步骤有三:
- 用一个节点G来暂存L->Next 用于释放该节点
- L=L->Next->Next
- free(G)
![fffc133762b320a1efe276d1ac355093.png](https://img-blog.csdnimg.cn/img_convert/fffc133762b320a1efe276d1ac355093.png)
你可能还有顾虑:要删除尾节点怎么办?
不用担心。
我们只需要调整判断的条件L->Next==P,
所以,当我们遍历到尾节点的前一个节点,执行和一般节点的删除的同样操作。
尾节点->Next为NULL,所以L->Next=NULL。
if (L->Next==P)
{
G=L->Next;
L->Next=L->Next->Next; //尾节点->Next为NULL,所以L->
free(G);
return Head;
}
如此,就删除了尾节点。
代码如下:
List Delete( List L, Position P ){
List Head=L,G;
// 删除头部
if(P==L)
{
L=L->Next;
return L;
}
while (L)
{
if (L->Next==P)
{
G=L->Next;
L->Next=L->Next->Next;
free(G);
return Head;
}
L=L->Next;
}
printf("Wrong Position for Deletionn");
return ERROR;
}
![53693e5626c62cf8b92fa3384951ad38.png](https://img-blog.csdnimg.cn/img_convert/53693e5626c62cf8b92fa3384951ad38.png)
编译器
C(gcc)
提交代码
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 Head=L,Node;
Node=(List)malloc(sizeof(List));
Node->Data=X;
Node->Next=NULL;
//头插
if (P==L)
{
Node->Next=L;
return Node;
}
while (L)
{
if (L->Next==P)
{
Node->Next=L->Next;
L->Next=Node;
return Head;
}
L=L->Next;
}
printf("Wrong Position for Insertionn");
return ERROR;
}
List Delete( List L, Position P ){
List Head=L,G;
// 删除头部
if(P==L)
{
L=L->Next;
return L;
}
while (L)
{
if (L->Next==P)
{
G=L->Next;
L->Next=L->Next->Next;
free(G);
return Head;
}
L=L->Next;
}
printf("Wrong Position for Deletionn");
return ERROR;
}
运行截图
![a71306a156adf836df4a4153368d8138.png](https://img-blog.csdnimg.cn/img_convert/a71306a156adf836df4a4153368d8138.png)
提交结果
![57c4827d5b615d0683fb418e359c2ee2.png](https://img-blog.csdnimg.cn/img_convert/57c4827d5b615d0683fb418e359c2ee2.png)
Ncie!Nice!Ncie!
搞定!
![cca91c33a25760517bad2dcaf54a96a2.png](https://img-blog.csdnimg.cn/img_convert/cca91c33a25760517bad2dcaf54a96a2.png)