PTA——6-3 带头结点的链式表操作集

什么是单链表?

单链表(一种链式存储结构的线性表)

链表由一个个节点组成,每个节点包含数据域和指针域,指针域指向下一个节点,元素在内存中可以不连续存储。

这一题跟上一道题PTA------6-2 顺序表操作集,非常的像,所以主要记忆上一道题的不同点

1.typedef struct LNode *PtrToLNode;新别名

2.存储的数据结构不一样了

顺序表:用数组**Data[MAXSIZE]**存储

通常用整数来表示元素的位置,也就是数组的下标

Last 表示顺序表中最后一个元素的位置

当顺序表为 时,Last 通常为**-1**

链式表(离散的):

ElementType Data 存储(可以将Data 理解为存储的一个具体的东西

位置通常用节点的指针来表示

当顺序表为 时, L->Next=NULL;

3.参数 L不同:

顺序表: L 是指向顺序表结构体的指针

链式表: L 是指向单链表头节点的指针

一、题目

函数接口定义:

List MakeEmpty();

Position Find( List L, ElementType X );

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

bool Delete( List L, Position P );

其中List结构定义如下:

typedef struct LNode *PtrToLNode;
struct LNode {

ElementType Data; //ElementType 是自定义的数据类型,它代表节点中存储的数据

PtrToLNode Next; //Next 是一个指向 struct LNode 结构体的指针,它用于指向下一个节点

};

typedef PtrToLNode Position; //这里把 PtrToLNode 类型重命名为 Position

typedef PtrToLNode List; //同样是把 PtrToLNode 类型重命名为 List

  • typedef 属于 C 语言的关键字,其作用是为已有的数据类型创建新的别名。
  • struct LNode 是一个结构体类型,不过此时还未对其具体内容进行定义。
  • struct LNode * 代表指向 struct LNode 结构体的指针类型。
  • PtrToLNode 就是为 struct LNode * 这个指针类型所定义的新别名。之后就可以用 PtrToLNode 来声明指向 struct LNode 结构体的指针了。

各个操作函数的定义为:

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

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

bool Insert( List L, ElementType X, Position P ):将X插入在位置P指向的结点之前,返回true。如果参数P指向非法位置,则打印"Wrong Position for Insertion",返回false;

bool Delete( List L, Position P ):将位置P的元素删除并返回true。若参数P指向非法位置,则打印"Wrong Position for Deletion"并返回false。

裁判测试程序样例:

#include <stdio.h>

#include <stdlib.h>

#define ERROR NULL

typedef enum {false, true} bool;

typedef int ElementType;

typedef struct LNode *PtrToLNode;

struct LNode {

ElementType Data;

PtrToLNode Next;

};

typedef PtrToLNode Position;

typedef PtrToLNode List;

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;

bool flag;

L = MakeEmpty();

scanf("%d", &N);

while ( N-- ) {

scanf("%d", &X);

flag = Insert(L, X, L->Next);

if ( flag==false ) 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 {

flag = Delete(L, P);

printf("%d is found and deleted.\n", X);

if ( flag==false )

printf("Wrong Answer.\n");

}

}

flag = Insert(L, X, NULL);

if ( flag==false ) printf("Wrong Answer\n");

else

printf("%d is inserted as the last element.\n", X);

P = (Position)malloc(sizeof(struct LNode));

flag = Insert(L, X, P);

if ( flag==true ) printf("Wrong Answer\n");

flag = Delete(L, P);

if ( flag==true ) printf("Wrong Answer\n");

for ( P=L->Next; 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

二、题解

List MakeEmpty()

List MakeEmpty(){

List L;

L=(PtrToLNode)malloc(sizeof(struct LNode)); //PtrToLNode:指针类型的名字,看题目所给的定义

L->Next=NULL; //这里的 Next 为指针了

return L;

}

Position Find( List L, ElementType X )

1.借助指针遍历链表,从链表的第一个 数据节点(L->Next)开始

2.利用while 循环遍历,查找 X 即 p->Data==X

注意:p=p->Next;
Position Find( List L, ElementType X ){

PtrToLNode p=L->Next; //将指针 p 初始化 为指向链表的第一个数据节点 (假设 L 是头节点,头节点本身可能不存储实际数据L->Next 指向第一个真正存储数据的节点

while(p){

if(p->Data==X){

return p; //返回本次指针

}

p=p->Next; //通过 p = p->Next 移动指针; Next是指向下一个指针的指针

}

return ERROR;

}

bool Insert( List L, ElementType X, Position P )

  1. w 用于指向新创建的节点

  2. 使用 malloc() 函数为新节点分配内存 空间,并将其地址赋值给指针**w**

  3. 让新节点连接到 P 节点之前,即 w->Next=P;

思路:

bool Insert( List L, ElementType X, Position P ){

PtrToLNode p=L,w;

while(p){

if(p->Next==P){

w=(PtrToLNode)malloc(sizeof(struct LNode)); //使用 malloc 函数为新节点分配内存空间,并将其地址赋值给指针 w

w->Data=X;

w->Next=P; //将新节点的 Next 指针指向指定位置 P,即让新节点连接到 P 节点之前

p->Next=w;

return true;

}

p=p->Next; //遍历,指向下一个节点用的(查找

}

printf("Wrong Position for Insertion\n");

return false;

}

bool Delete( List L, Position P )

1.跳过P指针 ,即 p->Next=P->Next

2.free(P); //使用 free 函数释放 P 节点所占用的内存
bool Delete( List L, Position P ){

PtrToLNode p=L;

while(p){

if(p->Next==P&&P!=NULL){ // 检查当前节点 p 的下一个节点是否为要删除的节点 P,并且 P 不为 NULL

p->Next=P->Next; //直接跳过P指针就可以了

free(P); //使用 free 函数释放 P 节点所占用的内存

return true;

}

p=p->Next;

}

printf("Wrong Position for Deletion\n");

return false;

}

三、答案

cpp 复制代码
List MakeEmpty(){
	List L;
	L=(PtrToLNode)malloc(sizeof(struct LNode));
	L->Next=NULL;
	return L;
}
Position Find( List L, ElementType X ){
	PtrToLNode p=L->Next; 
	while(p){
		if(p->Data==X){
			return p;
		}
		p=p->Next;
	}
	return ERROR;
}
bool Insert( List L, ElementType X, Position P ){
	PtrToLNode p=L,w;
	while(p){
		if(p->Next==P){
			w=(PtrToLNode)malloc(sizeof(struct LNode));
			w->Data=X;
			w->Next=P;p->Next=w;
			return true;
		}
		p=p->Next;
	}
	printf("Wrong Position for Insertion\n");
	return false; 
}
bool Delete( List L, Position P ){
	PtrToLNode p=L;
	while(p){
		if(p->Next==P&&P!=NULL){
			p->Next=P->Next;
			free(P);
			return true;
		}
		p=p->Next;
	}
	printf("Wrong Position for Deletion\n");
	return false;
}
相关推荐
夏寻.8 分钟前
在Windows系统中使用Docker发布镜像到镜像仓库
windows·docker
自由鬼2 小时前
基于Windows系统分析IT生态建设
linux·windows·生态建设
蓝黑20205 小时前
PowerShell从5.1升级到7.X
windows·powershell
RIKI_16 小时前
【浅学】Windows下ffmpeg+nginx+flv将本地视频推流在本地搭建的Web前端页面中播放,超详细步骤
windows·nginx·ffmpeg·html
开开心心就好9 小时前
快速搜索与管理PDF文档的专业工具
java·运维·windows·pdf·自动化·excel·音视频
迪小莫学AI11 小时前
# LeetCode 1007 行相等的最少多米诺旋转
windows·python·leetcode
0wioiw020 小时前
安卓基础(点击项目)
android·windows
Kusunoki_D1 天前
在 Windows 的终端安装并使用 azd 命令
windows·python·azd·azure cli
阿沁QWQ1 天前
C++ std::initializer_list 详解
数据结构·c++·windows·list