当前位置: 首页 > ds >正文

C语言单链表应用详解

链表是一种常用的数据结构,它在计算机科学中有广泛的应用。今天,我将带你深入了解单链表在C语言中的应用,通过一些经典的算法和实际项目,让你掌握单链表的强大功能。

 

单链表经典算法OJ题目

 

 

移除链表元素

移除链表中的指定元素,可以通过遍历链表并跳过需要移除的节点来实现。这在处理链表中的无效或重复数据时非常有用。

 

#include <stdio.h>

#include <stdlib.h>

 

typedef struct Node {

    int data;

    struct Node* next;

} Node;

 

Node* remove_elements(Node* head, int value) {

    Node* dummy = (Node*)malloc(sizeof(Node));

    dummy->next = head;

    Node* current = dummy;

    while (current->next != NULL) {

        if (current->next->data == value) {

            Node* temp = current->next;

            current->next = temp->next;

            free(temp);

        } else {

            current = current->next;

        }

    }

    return dummy->next;

}

 

int main() {

    // 示例代码

    return 0;

}

 

 

反转链表

反转链表是将链表的元素顺序完全颠倒。这在需要逆向处理链表数据时很有用。

 

Node* reverse_list(Node* head) {

    Node* prev = NULL;

    Node* current = head;

    while (current != NULL) {

        Node* next_node = current->next;

        current->next = prev;

        prev = current;

        current = next_node;

    }

    return prev;

}

 

 

合并两个有序链表

将两个已经排序的链表合并成一个有序链表。在处理多个有序数据源时非常高效。

Node* merge_sorted_lists(Node* l1, Node* l2) {

    Node* dummy = (Node*)malloc(sizeof(Node));

    Node* tail = dummy;

    while (l1 != NULL && l2 != NULL) {

        if (l1->data <= l2->data) {

            tail->next = l1;

            l1 = l1->next;

        } else {

            tail->next = l2;

            l2 = l2->next;

        }

        tail = tail->next;

    }

    tail->next = (l1 != NULL) ? l1 : l2;

    return dummy->next;

}

 

链表的中间结点

找出链表的中间节点。在需要快速访问链表中间数据时很有用。

 

Node* middle_node(Node* head) {

    Node* slow = head;

    Node* fast = head;

    while (fast != NULL && fast->next != NULL) {

        slow = slow->next;

        fast = fast->next->next;

    }

    return slow;

}

 

 

环形链表的约瑟夫问题

约瑟夫问题是一个经典的算法问题,通常用于模拟循环链表的应用场景。

 

#include <stdio.h>

#include <stdlib.h>

 

typedef struct Node {

    int data;

    struct Node* next;

} Node;

 

Node* josephus(int n, int m) {

    if (n == 0) return NULL;

    Node* head = (Node*)malloc(sizeof(Node));

    head->data = 1;

    head->next = head;

    Node* current = head;

    for (int i = 2; i <= n; i++) {

        Node* temp = (Node*)malloc(sizeof(Node));

        temp->data = i;

        temp->next = head;

        current->next = temp;

        current = temp;

    }

    current = head;

    while (current->next != current) {

        for (int i = 1; i < m; i++) {

            current = current->next;

        }

        Node* temp = current->next;

        current->next = temp->next;

        free(temp);

    }

    return current;

}

 

int main() {

    int n = 5, m = 3;

    Node* result = josephus(n, m);

    printf("The last remaining node is: %d\n", result->data);

    free(result);

    return 0;

}

 

 

基于单链表再实现通讯录项目

 

通讯录项目是一个经典的链表应用,用于管理联系人信息。相比于顺序表实现,链表实现的通讯录在插入和删除操作上更为高效。

 

 

功能要求

 

• 能够存储联系人的信息,如姓名、电话等。

 

• 支持增加、删除、查找联系人等功能。

 

 

数据结构定义

定义一个结构体来表示联系人信息:

 

typedef struct Contact {

    char name[50];

    char phone[20];

    struct Contact* next;

} Contact;

 

初始化通讯录

创建一个空的通讯录链表:

 

Contact* init_address_book() {

    return NULL;

}

 

增加联系人

向通讯录中添加新的联系人:

void add_contact(Contact** book, const char* name, const char* phone) {

    Contact* new_contact = (Contact*)malloc(sizeof(Contact));

    strcpy(new_contact->name, name);

    strcpy(new_contact->phone, phone);

    new_contact->next = *book;

    *book = new_contact;

}

 

查找联系人

在通讯录中查找指定姓名的联系人:

 

Contact* find_contact(Contact* book, const char* name) {

    Contact* current = book;

    while (current != NULL) {

        if (strcmp(current->name, name) == 0) {

            return current;

        }

        current = current->next;

    }

    return NULL;

}

 

删除联系人

从通讯录中删除指定姓名的联系人:

 

void delete_contact(Contact** book, const char* name) {

    Contact* current = *book;

    Contact* prev = NULL;

    while (current != NULL) {

        if (strcmp(current->name, name) == 0) {

            if (prev == NULL) {

                *book = current->next;

            } else {

                prev->next = current->next;

            }

            free(current);

            return;

        }

        prev = current;

        current = current->next;

    }

}

 

总结

通过本文的讲解,我们学习了单链表在C语言中的多种应用,包括经典算法和通讯录项目的实现。单链表的灵活性和效率使其成为处理动态数据的理想选择。希望这篇文章能帮助你更好地理解和应用单链表。

 

你在实现单链表应用的过程中,是否遇到过一些有趣的问题或挑战呢?欢迎在评论区留言分享,让我们一起交流学习!

http://www.xdnf.cn/news/6748.html

相关文章:

  • flutter缓存网络视频到本地,可离线观看
  • java 使用zxing生成条形码(可自定义文字位置、边框样式)
  • Chrome代理IP配置教程常见方式附问题解答
  • 华为网路设备学习-22(路由器OSPF-LSA及特殊详解)
  • 对称二叉树的判定:双端队列的精妙应用
  • python自学笔记2 数据类型
  • 性能测试详解
  • 在人脸识别项目中ffmpeg有什么作用
  • ESP32-S3学习笔记
  • el-table表格列宽度自适应
  • 微服务中服务降级和异常的区别
  • 课设:基于swin_transformer的植物中草药分类识别系统(包含数据集+UI界面+系统代码)
  • 基于支持向量机(SVM)的P300检测分类
  • Android SwitchButton 使用详解:一个实际项目的完美实践
  • redis数据结构-12(配置 RDB 快照:保存间隔和压缩)
  • okcc呼叫中心系统搭建的方案方式
  • 反向传播算法:神经网络的核心优化方法,一文打通任督二脉
  • [逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)
  • 基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
  • 内容中台重构企业知识管理路径
  • 英飞凌tle9954 GPIO
  • FPGA:Lattice的FPGA产品线以及器件选型建议
  • SQL里where条件的顺序影响索引使用吗?
  • 电子界桩在古建筑文物保护应用解决方案
  • 综合项目:博客
  • 保安员考试报名时,体检项目包含哪些?
  • Java回溯算法解决非递减子序列问题(LeetCode 491)的深度解析
  • 安全版4.5.8开启审计后,hac+读写分离主备切换异常
  • 算法刷题(Java与Python)1.二分查找
  • Linux补充之vscode连接远端主机