大家好,欢迎来到无限大的频道
今天给大家带来的是c语言
题目描述
创建一个双链表,并将链表中的数据输出到控制台,输入要查找的数据,将查找到的数据删除,并且显示删除后的链表
下面是一个用C语言实现的双链表(Doubly Linked List)程序,包括创建链表、输出链表、查找并删除数据的功能。代码会将链表的数据输出到控制台,并在删除指定数据后显示删除后的链表。
c
#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
函数中创建链表、打印原始链表、输入要删除的数据并最终打印删除后的链表。
更新
好的,下面是对原始双链表程序的进一步优化,实现了以下功能:
- 用户可以输入链表的初始值。
- 程序会在一个无限循环中,用户可以选择删除节点或在特定位置添加节点,直到用户选择退出。
- 提供更多选择功能,例如在头部、尾部或特定位置插入节点。
c
#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)
创建一个无限循环,让用户选择各种操作。 - 选择操作: 用户可以选择删除节点、在链表头部或尾部添加节点、在指定位置插入节点或退出程序。
- 内存释放: 在退出程序时,所有分配的内存会被释放,避免内存泄漏。
操作提示:
- 用户可以根据提示输入数据和选择执行的操作。
- 增加了在特定位置插入节点的功能,如果插入位置超出链表范围,则会将数据添加到尾部。
这个程序现在更加灵活,能够处理多种链表操作,便于用户进行动态的数据管理。