在链表形式中删除节点p呢?
时间: 2024-04-30 09:22:30 浏览: 8
在链表中删除节点p可以分为两种情况:
1. 如果p是头节点,直接将头节点指向p的下一个节点即可。
2. 如果p不是头节点,需要先找到p的前一个节点prev,然后将prev的next指针指向p的下一个节点。
具体的代码实现如下:
```python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def deleteNode(head: ListNode, p: ListNode) -> ListNode:
if not head or not p:
return head
if head == p:
return head.next
cur = head
while cur.next and cur.next != p:
cur = cur.next
if cur.next == p:
cur.next = p.next
return head
```
其中,head代表链表的头节点,p代表要删除的节点。在遍历链表的过程中,使用cur来表示当前节点,如果cur.next等于p,则说明cur的下一个节点就是要删除的节点,此时将cur的next指针指向p的下一个节点即可。最后返回头节点head即可。
相关问题
链表中函数参数*p与&p的区别
*p和&p是指针操作中常用的两种形式,它们有着不同的含义和作用。
1. *p:这是一个解引用操作符,用于获取指针p所指向的值。当我们使用*p时,实际上是获取了p所指向的内存地址中存储的值。
2. &p:这是一个取地址操作符,用于获取变量p的内存地址。当我们使用&p时,实际上是获取了变量p在内存中的地址。
总结起来,*p用于获取指针所指向的值,而&p用于获取变量的内存地址。它们在链表中的应用也有所不同:
- 在链表中,当我们声明一个指针变量p时,通常会将其指向链表中的某个节点。通过*p可以获取该节点存储的值。例如,如果p指向链表中的一个节点,可以使用*p来访问该节点存储的数据。
- 在链表中进行插入或删除节点操作时,我们可能需要修改指针变量的值,以保持链表的正确连接。这时候可以使用&p获取指针变量的地址,并通过赋值操作修改指针变量所指向的节点。
需要注意的是,*和&是指针操作符,在不同的上下文中具有不同的含义和作用。正确理解和使用它们对于链表等数据结构的操作是非常重要的。
用c语言写出一个图书管理系统里面包括录入新书借阅图书归还图书查找图书删除图书退出系统并保存书籍在book.txt文件中要使用链表形式
好的,我可以为您提供一些参考代码,您可以根据您的实际情况进行修改和优化。
首先,我们需要定义一个图书信息的结构体:
```c
typedef struct BookInfo {
char bookName[50]; // 书名
char author[20]; // 作者
int bookID; // 书号
int borrowed; // 是否被借阅,0表示未被借阅,1表示已被借阅
struct BookInfo *next; // 指向下一本书的指针
} BookInfo;
```
然后,我们可以定义一个链表来存储图书信息:
```c
BookInfo *head = NULL; // 链表头指针
```
接下来,我们可以实现录入新书的功能:
```c
void addBook() {
BookInfo *newBook = (BookInfo*) malloc(sizeof(BookInfo)); // 分配新的图书信息结构体
printf("请输入书名:");
scanf("%s", newBook->bookName);
printf("请输入作者名:");
scanf("%s", newBook->author);
printf("请输入书号:");
scanf("%d", &(newBook->bookID));
newBook->borrowed = 0; // 初始状态为未被借阅
newBook->next = NULL;
if (head == NULL) { // 链表为空,直接将新图书作为头节点
head = newBook;
} else { // 链表不为空,将新图书插入链表末尾
BookInfo *p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = newBook;
}
printf("录入成功!\n");
}
```
然后,我们可以实现借阅图书和归还图书的功能:
```c
void borrowBook() {
int bookID;
printf("请输入要借阅的图书的书号:");
scanf("%d", &bookID);
BookInfo *p = head;
while (p != NULL && p->bookID != bookID) { // 查找对应书号的图书
p = p->next;
}
if (p == NULL) { // 没有找到对应书号的图书
printf("未找到该书!\n");
} else if (p->borrowed == 1) { // 图书已被借阅
printf("该书已被借出!\n");
} else { // 图书未被借阅,可以借阅
p->borrowed = 1;
printf("借阅成功!\n");
}
}
void returnBook() {
int bookID;
printf("请输入要归还的图书的书号:");
scanf("%d", &bookID);
BookInfo *p = head;
while (p != NULL && p->bookID != bookID) { // 查找对应书号的图书
p = p->next;
}
if (p == NULL) { // 没有找到对应书号的图书
printf("未找到该书!\n");
} else if (p->borrowed == 0) { // 图书未被借阅,无需归还
printf("该书未被借出!\n");
} else { // 图书已被借阅,可以归还
p->borrowed = 0;
printf("归还成功!\n");
}
}
```
接着,我们可以实现查找图书和删除图书的功能:
```c
void searchBook() {
char bookName[50];
printf("请输入要查找的图书的书名:");
scanf("%s", bookName);
BookInfo *p = head;
while (p != NULL && strcmp(p->bookName, bookName) != 0) { // 查找对应书名的图书
p = p->next;
}
if (p == NULL) { // 没有找到对应书名的图书
printf("未找到该书!\n");
} else { // 找到了对应书名的图书
printf("书名:%s\n", p->bookName);
printf("作者:%s\n", p->author);
printf("书号:%d\n", p->bookID);
printf("借阅状态:%s\n", p->borrowed == 0 ? "未借出" : "已借出");
}
}
void deleteBook() {
int bookID;
printf("请输入要删除的图书的书号:");
scanf("%d", &bookID);
BookInfo *p = head;
BookInfo *q = NULL;
while (p != NULL && p->bookID != bookID) { // 查找对应书号的图书
q = p;
p = p->next;
}
if (p == NULL) { // 没有找到对应书号的图书
printf("未找到该书!\n");
} else { // 找到了对应书号的图书,可以删除
if (q == NULL) { // 要删除的是头节点
head = p->next;
} else {
q->next = p->next;
}
free(p);
printf("删除成功!\n");
}
}
```
最后,我们可以实现退出系统并保存书籍的功能:
```c
void saveBooks() {
FILE *fp = fopen("book.txt", "w"); // 打开文件,以写入方式打开
if (fp == NULL) {
printf("文件打开失败!\n");
return;
}
BookInfo *p = head;
while (p != NULL) { // 将链表中的图书信息写入文件
fprintf(fp, "%s %s %d %d\n", p->bookName, p->author, p->bookID, p->borrowed);
p = p->next;
}
fclose(fp); // 关闭文件
}
void quitSystem() {
saveBooks(); // 保存图书信息
BookInfo *p = head;
while (p != NULL) { // 释放链表中的内存
BookInfo *q = p;
p = p->next;
free(q);
}
printf("已退出系统!\n");
}
```
至此,一个简单的图书管理系统就完成了。您可以根据您的实际需求进行修改和优化。