c语言实例

大家好,欢迎来到无限大的频道

今天给大家带来的是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;  
}  

代码说明

  1. 结构体定义 : 定义一个双链表节点结构体 Node,包含数据、指向下一个节点的指针和指向上一个节点的指针。
  2. 创建新节点 : createNode 函数用于创建新节点并初始化它的值。
  3. 添加节点 : append 函数在链表末尾添加新节点。
  4. 打印链表 : printList 函数遍历链表并打印每个节点的数据。
  5. 删除节点 : deleteNode 函数查找指定值的节点,找到后删除它,并调整链表的指针。
  6. 主函数 : 在 main 函数中创建链表、打印原始链表、输入要删除的数据并最终打印删除后的链表。

更新

好的,下面是对原始双链表程序的进一步优化,实现了以下功能:

  1. 用户可以输入链表的初始值。
  2. 程序会在一个无限循环中,用户可以选择删除节点或在特定位置添加节点,直到用户选择退出。
  3. 提供更多选择功能,例如在头部、尾部或特定位置插入节点。
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;
}

新增功能说明:

  1. 用户输入初始值: 程序请求用户输入链表节点的数量和每个节点的数据,生成初始链表。
  2. 无限循环 : 使用 while(1) 创建一个无限循环,让用户选择各种操作。
  3. 选择操作: 用户可以选择删除节点、在链表头部或尾部添加节点、在指定位置插入节点或退出程序。
  4. 内存释放: 在退出程序时,所有分配的内存会被释放,避免内存泄漏。

操作提示:

  • 用户可以根据提示输入数据和选择执行的操作。
  • 增加了在特定位置插入节点的功能,如果插入位置超出链表范围,则会将数据添加到尾部。

这个程序现在更加灵活,能够处理多种链表操作,便于用户进行动态的数据管理。

相关推荐
ZSYP-S23 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos30 分钟前
C++----------函数的调用机制
java·c++·算法
唐叔在学习34 分钟前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA1 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo1 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
FeboReigns1 小时前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns1 小时前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++
游是水里的游2 小时前
【算法day20】回溯:子集与全排列问题
算法
_小柏_2 小时前
C/C++基础知识复习(43)
c语言·开发语言·c++