大家好,欢迎来到无限大的频道
今天给大家带来的是c语言
题目描述
创建一个双链表,并将链表中的数据输出到控制台,输入要查找的数据,将查找到的数据删除,并且显示删除后的链表
下面是一个用C语言实现的双链表(Doubly Linked List)程序,包括创建链表、输出链表、查找并删除数据的功能。代码会将链表的数据输出到控制台,并在删除指定数据后显示删除后的链表。
#include <stdio.h>
#include <stdlib.h> // 定义双链表节点
typedef struct Node { int data; struct Node* next; struct Node* prev;
} Node; // 创建新节点
Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; newNode->prev = NULL; return newNode;
} // 在链表末尾添加节点
void append(Node** head_ref, int new_data) { Node* new_node = createNode(new_data); Node* last = *head_ref; if (*head_ref == NULL) { *head_ref = new_node; return; } while (last->next != NULL) last = last->next; last->next = new_node; new_node->prev = last;
} // 打印链表
void printList(Node* node) { while (node != NULL) { printf("%d ", node->data); node = node->next; } printf("\n");
} // 查找并删除节点
void deleteNode(Node** head_ref, int key) { Node* temp = *head_ref; // 如果头节点包含要删除的值 if (temp != NULL && temp->data == key) { *head_ref = temp->next; if (*head_ref != NULL) (*head_ref)->prev = NULL; free(temp); return; } // 查找要删除的节点 while (temp != NULL && temp->data != key) temp = temp->next; // 如果未找到要删除的节点 if (temp == NULL) { printf("未找到数据为 %d 的节点。\n", key); return; } // 更改指针以删除节点 if (temp->next != NULL) temp->next->prev = temp->prev; if (temp->prev != NULL) temp->prev->next = temp->next; free(temp);
} // 主函数
int main() { Node* head = NULL; // 创建链表并添加数据 append(&head, 10); append(&head, 20); append(&head, 30); append(&head, 40); printf("原始链表: "); printList(head); int dataToDelete; printf("请输入要删除的数据: "); scanf("%d", &dataToDelete); deleteNode(&head, dataToDelete); printf("删除后的链表: "); printList(head); return 0;
}
代码说明
- 结构体定义: 定义一个双链表节点结构体
Node
,包含数据、指向下一个节点的指针和指向上一个节点的指针。 - 创建新节点:
createNode
函数用于创建新节点并初始化它的值。 - 添加节点:
append
函数在链表末尾添加新节点。 - 打印链表:
printList
函数遍历链表并打印每个节点的数据。 - 删除节点:
deleteNode
函数查找指定值的节点,找到后删除它,并调整链表的指针。 - 主函数: 在
main
函数中创建链表、打印原始链表、输入要删除的数据并最终打印删除后的链表。
更新
好的,下面是对原始双链表程序的进一步优化,实现了以下功能:
- 用户可以输入链表的初始值。
- 程序会在一个无限循环中,用户可以选择删除节点或在特定位置添加节点,直到用户选择退出。
- 提供更多选择功能,例如在头部、尾部或特定位置插入节点。
#include <stdio.h>
#include <stdlib.h>// 定义双链表节点
typedef struct Node {int data;struct Node* next;struct Node* prev;
} Node;// 创建新节点
Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;newNode->prev = NULL;return newNode;
}// 在链表末尾添加节点
void append(Node** head_ref, int new_data) {Node* new_node = createNode(new_data);Node* last = *head_ref;if (*head_ref == NULL) {*head_ref = new_node;return;}while (last->next != NULL)last = last->next;last->next = new_node;new_node->prev = last;
}// 在链表头部添加节点
void prepend(Node** head_ref, int new_data) {Node* new_node = createNode(new_data);new_node->next = *head_ref;if (*head_ref != NULL)(*head_ref)->prev = new_node;*head_ref = new_node;
}// 在指定位置插入节点
void insertAfter(Node* prev_node, int new_data) {if (prev_node == NULL) {printf("前一个节点不可为NULL。\n");return;}Node* new_node = createNode(new_data);new_node->next = prev_node->next;prev_node->next = new_node;new_node->prev = prev_node;if (new_node->next != NULL)new_node->next->prev = new_node;
}// 打印链表
void printList(Node* node) {while (node != NULL) {printf("%d ", node->data);node = node->next;}printf("\n");
}// 查找并删除节点
void deleteNode(Node** head_ref, int key) {Node* temp = *head_ref;// 如果头节点包含要删除的值if (temp != NULL && temp->data == key) {*head_ref = temp->next;if (*head_ref != NULL)(*head_ref)->prev = NULL;free(temp);return;}// 查找要删除的节点while (temp != NULL && temp->data != key)temp = temp->next;// 如果未找到要删除的节点if (temp == NULL) {printf("未找到数据为 %d 的节点。\n", key);return;}// 更改指针以删除节点if (temp->next != NULL)temp->next->prev = temp->prev;if (temp->prev != NULL)temp->prev->next = temp->next;free(temp);
}// 主函数
int main() {Node* head = NULL;int initialValue, numOfNodes;// 用户输入链表的初始值printf("请输入链表的节点数量: ");scanf("%d", &numOfNodes);for (int i = 0; i < numOfNodes; i++) {printf("请输入第 %d 个值: ", i + 1);scanf("%d", &initialValue);append(&head, initialValue);}while (1) {printf("\n当前链表: ");printList(head);int choice, data, pos;printf("选择操作:1. 删除节点 2. 在头部添加节点 3. 在尾部添加节点 4. 在指定位置插入节点 5. 退出\n");printf("请输入你的选择: ");scanf("%d", &choice);switch (choice) {case 1:printf("请输入要删除的数据: ");scanf("%d", &data);deleteNode(&head, data);break;case 2:printf("请输入要添加到头部的数据: ");scanf("%d", &data);prepend(&head, data);break;case 3:printf("请输入要添加到尾部的数据: ");scanf("%d", &data);append(&head, data);break;case 4:printf("请输入要插入的位置(从1开始): ");scanf("%d", &pos);printf("请输入要插入的数据: ");scanf("%d", &data);{Node* current = head;for (int i = 1; current != NULL && i < pos; i++) {current = current->next;}// 如果是插入头部if (pos == 1) {prepend(&head, data);} else if (current != NULL) {insertAfter(current->prev, data);} else {printf("插入位置超出链表范围,添加到尾部。\n");append(&head, data);}}break;case 5:printf("退出程序。\n");// 释放链表内存while (head != NULL) {Node* temp = head;head = head->next;free(temp);}return 0;default:printf("无效选择,请重试。\n");break;}}return 0;
}
新增功能说明:
- 用户输入初始值: 程序请求用户输入链表节点的数量和每个节点的数据,生成初始链表。
- 无限循环: 使用
while(1)
创建一个无限循环,让用户选择各种操作。 - 选择操作: 用户可以选择删除节点、在链表头部或尾部添加节点、在指定位置插入节点或退出程序。
- 内存释放: 在退出程序时,所有分配的内存会被释放,避免内存泄漏。
操作提示:
- 用户可以根据提示输入数据和选择执行的操作。
- 增加了在特定位置插入节点的功能,如果插入位置超出链表范围,则会将数据添加到尾部。
这个程序现在更加灵活,能够处理多种链表操作,便于用户进行动态的数据管理。